使用Flask/Jinja2将HTML传递给模板

271

我正在为 Flask 和 SQLAlchemy 构建管理界面,并希望通过 render_template 将不同输入类型的 HTML 传递到我的视图。模板框架似乎会自动转义 HTML,因此所有的 <"'> 字符都会被转换为 HTML 实体。如何禁用这个功能,以便 HTML 能够正确地呈现?

7个回答

520

要在渲染值时关闭自动转义,请使用|safe过滤器。

{{ something|safe }}

只有在信任数据的情况下才应该这样做,因为渲染未经转义的不可信数据会存在跨站点脚本漏洞。


150

MarkupSafe 提供了 Jinja 的自动转义行为。您可以导入 Markup 并将其用于声明代码中的值是 HTML 安全的:

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

将其传递给模板,您就不必对其使用|safe过滤器。


48

从Jinja文档的HTML转义部分:

当启用自动转义时,默认情况下会转义所有内容,除非明确标记为安全的值。这些值可以由应用程序标记,也可以在模板中使用|safe过滤器标记。

例如:

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

19

当你有很多不需要转义的变量时,你可以使用autoescape覆盖块:

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

4

对于处理换行符,我尝试了几个选项,最终选择了这个:

{% set list1 = data.split('\n') %}
{% for item in list1 %}
{{ item }}
  {% if not loop.last %}
  <br/>
  {% endif %}
{% endfor %}

这种方法的好处是与自动转义兼容,保持所有内容安全可靠。还可以与过滤器(如urlize)结合使用。

当然,这与Helge的答案类似,但不需要宏(而是依赖于Jinja内置的split函数),并且在最后一项之后也不会添加不必要的 <br/> 标签。


2

有些人似乎关闭了自动转义,这会带来安全风险,以操纵字符串显示。

如果您只想在字符串中插入一些换行符并将其转换为<br />,那么您可以使用类似于jinja宏的方法:

{% 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 ) }}

2
在您的模板中使用safe过滤器,然后在视图中使用 bleach来对HTML进行消毒处理。使用bleach,您可以列出您需要使用的HTML标签。
据我所知,这是最安全的方法。我尝试了safe过滤器和Markup类,但两种方式都允许我执行不必要的JavaScript。非常不安全!

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接