在 Django 模板中的 JSON 中安全地使用带有 html 的 JSON

Posted

技术标签:

【中文标题】在 Django 模板中的 JSON 中安全地使用带有 html 的 JSON【英文标题】:Safely Using JSON with html inside of the JSON in Django Templates 【发布时间】:2012-12-26 18:20:45 【问题描述】:

如何在 django webapp 中安全地渲染 JSON 数据?

在 django 的服务器上,我生成 JSON 数据,然后在 django 模板中呈现该 JSON 数据。 JSON 偶尔包含 html 的 sn-ps。大多数时候,这很好,但是如果 </script> 标记在呈现时位于 JSON 数据中,它会破坏周围的 javascript

例如...

在服务器上,在 python 中我会有这个:

template_data = 
    'my_json' : '["my_snippet": "<b>Happy HTML</b>"]'

# pass the template data to the django template
return render_to_response('my_template.html', template_data, context_instance = c)

然后在模板中

<script type="text/javascript">
var the_json = my_json|safe;
</script>
... some html ...

生成的 html 工作正常,如下所示:

<script type="text/javascript">
var the_json = ["my_snippet": "<b>Happy HTML</b>"];
</script>
... some html ...

但是,当 JSON 在服务器上看起来像这样时,您会遇到问题:

template_data = 
    'my_json' : '["my_snippet": "Bad HTML</script>"]'

return render_to_response('my_template.html', template_data, context_instance = c)

现在,当它被渲染时,你会得到:

<script type="text/javascript">
var the_json = ["my_snippet": "Bad HTML</script>"];
</script>
... some html ...

JSON 代码中的关闭脚本标记被视为关闭整个脚本块。然后你的所有 javascript 都会中断。

一种可能的解决方案是在将模板数据传递给模板时检查&lt;/script&gt;,但我觉得有更好的方法。

【问题讨论】:

您可以将其作为 json(通过 AJAX)提供或作为 javascript 文件提供(然后使用脚本标签包含它)。 【参考方案1】:

安全地将 JSON 作为字符串插入,然后对其调用 JSON.parse

使用escapejs 而不是安全的。它是为输出到 JavaScript 而设计的。

var the_json = 'my_json|escapejs';

要获取 JavaScript 对象,您需要在该字符串上调用 JSON.parse。出于安全原因,这总是比将 JSON 编码转储到您的脚本中并直接评估它更可取。

我使用的将 python 对象直接发送到客户端的有用过滤器是这样的:

@register.filter
def to_js(value):
    """
    To use a python variable in JS, we call json.dumps to serialize as JSON server-side and reconstruct using
    JSON.parse. The serialized string must be escaped appropriately before dumping into the client-side code.
    """
    # separators is passed to remove whitespace in output
    return mark_safe('JSON.parse("%s")' % escapejs(json.dumps(value, separators=(',', ':'))))

并像这样使用它:

var Settings =  js_settings|to_js ;

【讨论】:

如果你这样做了,那么the_json 会变成一个字符串,而不是一个 javascript json 对象。 你可以做var the_json = JSON.parse(my_json|escapejs) 我认为你需要引用它,像这样:var the_json = JSON.parse('my_json|escapejs') 第一行将简单地将字符串安全地放入您的javascript。然后您需要反序列化,这就是我创建过滤器的原因。您绝对应该使用JSON.parse,而不是希望它在任何情况下都被解析为合法对象。 要正确地进行嵌套转义非常棘手,即使我完全理解了这个问题,我也无法完全摆脱它。非常感谢 Andrew(很好地)记录了执行此操作的正确方法!

以上是关于在 Django 模板中的 JSON 中安全地使用带有 html 的 JSON的主要内容,如果未能解决你的问题,请参考以下文章

在Django模板中安全地包含JavaScript数据

django - 使用间隔的 AJAX 调用刷新模板中的 JSON 数据

在Django模板中使用json数据

Django-模板中的Json数据

解析json在模板中的django modelformset中返回

如何将 django 变量正确转换为模板中的 json