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

我正在为Flask和SQLAlchemy构建一个管理,我想通过使用render_template将不同输入的HTML传递到我的视图。模板框架似乎自动转义HTML,因此所有<"'>字符都转换为HTML实体。我如何禁用它,以使HTML正确呈现?

154489 次浏览

要在呈现值时关闭自动转义,请使用|safe筛选器。

\{\{ something|safe }}

只对您信任的数据执行此操作,因为呈现不受信任的数据而不转义是跨站点脚本漏洞。

MarkupSafe提供了Jinja的自动转义行为。你可以导入Markup并使用它从代码中声明一个HTML安全的值:

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

把它传递给模板,你不必对它使用|safe过滤器。

来自Jinja docs部分< em > HTML转义< / em >:

当自动转义被启用时,默认情况下所有内容都会被转义 除了显式标记为安全的值。它们可以是 由应用程序或模板中使用|safe标记 过滤器。< / p >

例子:

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

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

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

有些人似乎关闭了携带安全风险autoescape来操作字符串显示。

如果你只想在字符串中插入一些换行符并将换行符转换为<br />,那么你可以像这样使用金贾的宏:

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

在你的模板中调用这个with

\{\{ linebreaks_for_string( my_string_in_a_variable ) }}

为了特别处理换行符,我尝试了许多选项,最后选择了这个:

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

这种方法的优点是它与自动转义兼容,使一切都保持良好和安全。它还可以与过滤器结合使用,比如urlize。

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

在模板中使用safe过滤器,然后在视图中使用bleach清理HTML。使用漂白剂,您可以将需要使用的HTML标记列入白名单。

据我所知,这是最安全的。我尝试了safe过滤器和Markup类,这两种方式都允许我执行不需要的JavaScript。不太安全!