Jinja2 将特定 HTML 标签标记为安全

Moj*_*imi 5 python jinja2 flask python-3.x

我知道 jinja 中有安全过滤器和逃生过滤器,但我找不到解决我的问题的方法。

我有以下字符串:

mystring = """<script>alert('I'm unsafe')</script>

I just entered a new line


Two new lines now!"""
Run Code Online (Sandbox Code Playgroud)

我想在<p>正确显示换行符的标签中使用它:

<p>{{mystring | replace('\n', '<br>')}}</p>
Run Code Online (Sandbox Code Playgroud)

这不起作用,因为 Jinja2 自动转义 HTML 标签,但如果我这样做:

<p>{{mystring | replace('\n', '<br>') | safe }}</p>
Run Code Online (Sandbox Code Playgroud)

那么就会不安全。

我尝试过的是:

<p>{{mystring | escape | replace('\n', '<br>') | safe }}</p>
Run Code Online (Sandbox Code Playgroud)

但上面的方法不起作用,<br>由于某种原因 s 仍然被转义

怎样才能让<br>标签不被转义呢?

ciz*_*rio 2

要将<br>标签标记为安全,解决方案是使用此处所述的自定义过滤器

下面是一个小示例过滤器,它将文本分解为 HTML 换行符和段落,并在启用自动转义的情况下将返回值标记为安全 HTML 字符串:

通过一些自定义,您可以根据您的情况调整逻辑:

创建filters.py(使应用程序模块化)

import re
from jinja2 import evalcontextfilter, Markup, escape

_paragraph_re = re.compile(r'(\n)')

@evalcontextfilter
def nl2br(eval_ctx, value):

    result = ''.join('%s' % p.replace('\n', Markup('<br>'))
        for p in _paragraph_re.split(escape(value)))

    if eval_ctx.autoescape:
        result = Markup(result)

    return result
Run Code Online (Sandbox Code Playgroud)

然后在app.py

from flask import Flask

from .filters import nl2br

app = Flask(__name__)
[..]
app.jinja_env.filters['nl2br'] = nl2br
Run Code Online (Sandbox Code Playgroud)

然后在你的模板中

<p>{{ mystring | nl2br }}</p>

Run Code Online (Sandbox Code Playgroud)