【问题标题】:Safely Using JSON with html inside of the JSON in Django Templates在 Django 模板中的 JSON 中安全地使用带有 html 的 JSON
【发布时间】: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 文件提供(然后使用脚本标签包含它)。

标签: javascript python html django


【解决方案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(很好地)记录了执行此操作的正确方法!
猜你喜欢
  • 1970-01-01
  • 2011-11-04
  • 1970-01-01
  • 2011-09-11
  • 1970-01-01
  • 1970-01-01
  • 2020-08-03
  • 2012-03-03
  • 2013-11-03
相关资源
最近更新 更多