在 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 都会中断。
一种可能的解决方案是在将模板数据传递给模板时检查</script>
,但我觉得有更好的方法。
【问题讨论】:
您可以将其作为 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 - 使用间隔的 AJAX 调用刷新模板中的 JSON 数据