การส่ง HTML ไปยังเทมเพลตโดยใช้ Flask / Jinja2


163

ฉันสร้างผู้ดูแลระบบสำหรับขวดและ SQLAlchemy และฉันต้องการที่จะผ่าน HTML render_templateสำหรับปัจจัยการผลิตที่แตกต่างกันไปที่มุมมองของฉันโดยใช้ เฟรมเวิร์กการสร้างเท็มเพลตดูเหมือนว่าจะหลบหนี html โดยอัตโนมัติดังนั้น <"'> ทั้งหมดจะถูกแปลงเป็นเอนทิตี html ฉันจะปิดการใช้งานเพื่อให้ HTML แสดงอย่างถูกต้องได้อย่างไร

คำตอบ:


344

วิธีที่เหมาะคือการ

{{ something|safe }}

กว่าการปิดการหลบหนีโดยอัตโนมัติ


2
สวัสดี @Armin Ronacher คุณช่วยอธิบายเพิ่มเติมและยกตัวอย่างได้ไหม ขอบคุณ
Samoth

ฉันหมายถึงตัวอย่างเช่นฉันมีไฟล์ที่เรียกว่าuserHome.htmlและฉันต้องการที่จะใช้return render_template('userHome.html')แต่มันไม่ได้แสดงอย่างถูกต้องและทุกคนหันไปใช้หน่วยงาน HTMLในคอนโซลโครเมี่ยมของฉัน
Samoth

ในtransแท็กนี้จะต้องใช้เป็น{% trans something=something|safe %}A {{something}} B{% endtrans %}
Kangur

1
เป็นเรื่องที่ควรกล่าวถึงว่าคุณควรระมัดระวังในการหลีกเลี่ยงช่องโหว่Cross-Site Scriptingเมื่อคุณทำเช่นนี้เนื่องจากคุณปิดการใช้งานการป้องกันการฝังตัวของไลบรารี่ของไลบรารีเทมเพลต
Harry Cutts

108

คุณสามารถประกาศ HTML ให้ปลอดภัยจากรหัส:

from flask import Markup
value = Markup('<strong>The HTML String</strong>')

จากนั้นส่งผ่านค่านั้นไปยังเทมเพลตและพวกเขาไม่จำเป็นต้อง|safeใช้


4
มาร์กอัปเป็นคลาส Jinja2 ใช่ ใช้อินเทอร์เฟซทั่วไปที่สนับสนุนโดยไลบรารีหลามหลายแห่ง (น่าเสียดายที่ไม่ใช่ Django) นอกจากนี้คุณยังสามารถใช้แพคเกจความปลอดภัยมาร์กอัปที่ใช้วัตถุเดียวกัน: pypi.python.org/pypi/MarkupSafe
Armin Ronacher

มันมีอยู่ใน jinja2
Giovanni G. PY

23

จาก jinja docs section HTML Escaping :

เมื่อเปิดใช้งานการหลบหนีโดยอัตโนมัติทุกอย่างจะถูกหลบหนีโดยค่าเริ่มต้นยกเว้นค่าที่ทำเครื่องหมายไว้อย่างชัดเจนว่าปลอดภัย แอปพลิเคชันหรือในเทมเพลตสามารถทำได้โดยใช้ตัวกรอง | safe

ตัวอย่าง:

 <div class="info">
   {{data.email_content|safe}}
 </div>

5

เมื่อคุณมีตัวแปรจำนวนมากที่ไม่ต้องการหลบหนีคุณสามารถใช้autoescapeบล็อก:

{% autoescape off %}
{{ something }}
{{ something_else }}
<b>{{ something_important }}</b>
{% endautoescape %}

1

บางคนดูเหมือนจะปิดautoescapeซึ่งมีความเสี่ยงด้านความปลอดภัยในการจัดการการแสดงผลสตริง

หากคุณต้องการแทรก linebreaks บางตัวลงในสตริงและแปลง linebreaks ให้เป็นส่วน<br />หนึ่งคุณสามารถใช้jinja macroเช่น:

{% macro linebreaks_for_string( the_string ) -%}
{% if the_string %}
{% for line in the_string.split('\n') %}
<br />
{{ line }}
{% endfor %}
{% else %}
{{ the_string }}
{% endif %}
{%- endmacro %}

และในเทมเพลตของคุณเพียงแค่เรียกสิ่งนี้ด้วย

{{ linebreaks_for_string( my_string_in_a_variable ) }}
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.