为什么以及何时使用 Django mark_safe() 函数

Why and When to use Django mark_safe() function

看了文档,mark_safe()的功能还是不清楚。我想这与 CSRF 相关。但是为什么以及什么时候应该使用 mark_safe() 呢?

这是文档

mark_safe(s)

Explicitly mark a string as safe for (HTML) output purposes. The returned object can be used everywhere a string or unicode object is appropriate.

Can be called multiple times on a single string.

For building up fragments of HTML, you should normally be using django.utils.html.format_html() instead.

String marked safe will become unsafe again if modified. For example:

Django 是一个框架,它默认尝试做 "the right" 事情。这意味着当您做最简单的事情时,您很可能在做正确的事情。

现在让我们看一下 php 和 python 中的一些模板:

PHP:

<? echo $foo ?>

可能会给出:

<script src="evil">

姜戈:

{{ foo }}

给出相同的输入:

&gt;script src="evil"&lt;

现在假设,您想放置一个 link <a href="link">text</a>。然后 django 将再次使用 &lt;&gt; 将其呈现为文本。如果您知道自己在做什么,现在可以使用 mark_safe 来表示该文本是可信的(即不是来自用户输入)。

作为django程序员,通常你会在你的模板中使用{{ foo|safe }}{% autoescape off %}{{ foo }}{% endautoescape %},当字符串被声明为安全时更清楚。

那么,mark_safe用在哪里呢?当您编写自己的模板标签或过滤器时,您需要将字符串标记为来自 python 的安全字符串,因为开发人员会假设 {{ foo|mylinkifyfunction }} 做正确的事情(即它转义了 url foo,但没有转义 url 周围的 <a href=""></a>

还值得注意的是,在构建 HTML 代码片段时,建议使用 format_html(...) 函数而不是 mark_safe 并转义其所有参数。

所以,而不是写:

mark_safe("%s <b>%s</b> %s" % (
    some_html,
    escape(some_text),
    escape(some_other_text),
))

您应该改用:

format_html("{} <b>{}</b> {}",
    mark_safe(some_html),
    some_text,
    some_other_text,
)

这样做的好处是您无需将 escape() 应用于每个参数,如果您忘记了一个参数,则有出现错误和 XSS 漏洞的风险。