看了文档,对mark_safe()的功能还是不太清楚。我想这与 CSRF 相关。但是为什么以及什么时候应该使用 mark_safe() 呢?
这是文档
mark_safe(s)
明确标记一个字符串对于 (HTML) 是安全的 输出目的。返回的对象可以在任何地方使用一个字符串 或 unicode 对象是合适的。
可以在单个字符串上多次调用。
为了构建 HTML 片段,您通常应该使用 django.utils.html.format_html() 代替。
如果修改了标记为安全的字符串将再次变得不安全。例如:
Django 是一个框架,它默认尝试做“正确”的事情。这意味着当您做最简单的事情时,您可能正在做正确的事情。
现在让我们看一下 php 和 python 中的一些模板:
PHP:
<? echo $foo ?>
可以给:
<script src="evil">
姜戈:
{{ foo }}
给出相同的输入:
>script src="evil"<
现在假设,您想放置一个链接
<a href="link">text</a>
。然后 django 将再次使用 <>
将其呈现为文本。如果您知道自己在做什么,您现在可以使用 mark_safe
来表示该文本是可信的(即不是来自用户输入)。
作为django程序员,通常你会在你的模板中使用
{{ foo|safe }}
或{% autoescape off %}{{ foo }}{% endautoescape %}
,当字符串被声明为安全时更清楚。
那么,
mark_safe
用在哪里呢?当您编写自己的模板标签或过滤器时,您需要将字符串标记为对 python 安全,因为开发人员会假设,{{ foo|mylinkifyfunction }}
做了正确的事情,即它转义了 url foo,但没有转义 HTML 代码<a href=""></a>
网址周围。
一个示例实现可以是:
def mylinkifyfunction(url):
escaped_url = escape_url(url) # Take care of escaping the URL in a safe way
generated_html = f'<a href="{escaped_url}">{escaped_url}</a>' # This string could be dangerous, if it would use url instead of escaped_url
return mark_safe(generated_html) # mark the string as safe, because it should be rendered as unescaped HTML
示例假设
escape_url
返回一个不包含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 漏洞的风险。