阅读文档后,mark_safe()似乎仍然是一个神话。我想这与CSRF有关。但是为什么以及何时使用mark_safe()?
这是文档
mark_safe(S)[来源]¶
将字符串明确标记为(HTML)安全 输出目的。返回的对象可以在字符串的任何地方使用 或unicode对象是合适的。
可以在一个字符串上多次调用。
要构建HTML片段,通常应该使用 django.utils.html.format_html()代替。
如果修改,标记为安全的字符串将再次变得不安全。例如:
答案 0 :(得分:16)
Django是一个框架,试图做正确的"事情默认。这意味着当你做最简单的事情时,你可以做出正确的事情。
现在让我们看看php和python中的一些模板:
PHP:
<? echo $foo ?>
可以给:
<script src="evil">
Django的:
{{ foo }}
给出相同的输入:
>script src="evil"<
现在假设您要放置一个链接<a href="link">text</a>
。然后django将再次使用<>
将其呈现为文本。如果您知道自己在做什么,现在可以使用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漏洞。