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

时间:2015-09-26 16:55:05

标签: django django-templates

阅读文档后,mark_safe()似乎仍然是一个神话。我想这与CSRF有关。但是为什么以及何时使用mark_safe()?

这是文档

  

mark_safe(S)[来源]¶

     

将字符串明确标记为(HTML)安全   输出目的。返回的对象可以在字符串的任何地方使用   或unicode对象是合适的。

     

可以在一个字符串上多次调用。

     

要构建HTML片段,通常应该使用   django.utils.html.format_html()代替。

     

如果修改,标记为安全的字符串将再次变得不安全。例如:

2 个答案:

答案 0 :(得分:16)

Django是一个框架,试图做正确的"事情默认。这意味着当你做最简单的事情时,你可以做出正确的事情。

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

PHP:

<? echo $foo ?>

可以给:

<script src="evil">

Django的:

{{ foo }}

给出相同的输入:

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

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

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

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

答案 1 :(得分:2)

还值得注意的是,在构建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(),并且如果忘记了一个参数,则可能会遇到bug和XSS漏洞。