简体   繁体   English

在Django模板中安全地使用JSON和JSON内部的JSON

[英]Safely Using JSON with html inside of the JSON in Django Templates

How do you safely render JSON data in a django webapp? 你如何在django webapp中安全地呈现JSON数据?

On the server in django I generate JSON data and then render that JSON data in a django template. 在django的服务器上,我生成JSON数据,然后在django模板中呈现该JSON数据。 The JSON occasionally contains snippets of html. JSON偶尔会包含html的片段。 Most of the time, that's fine, however if the </script> tag is inside the JSON data when it is rendered, it destroys the surrounding javascript. 大多数情况下,没关系,但是如果</script>标记在呈现时在JSON数据中,它会破坏周围的javascript。

For example... 例如...

On the server , in python I'll have this: 在服务器上 ,在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)

And then in the template : 然后在模板中

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

The resulting html works fine and looks like this: 生成的html工作正常,看起来像这样:

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

However, you run into problems when, on the server, the JSON looks like this: 但是,当在服务器上,JSON看起来像这样时,会遇到问题:

template_data = {
    'my_json' : '[{"my_snippet": "Bad HTML</script>"}]'
}
return render_to_response('my_template.html', template_data, context_instance = c)

Now, when it's rendered, you'll get: 现在,当它被渲染时,你会得到:

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

The closing script tag within the JSON code is treated as closing the entire script block. JSON代码中的结束脚本标记被视为关闭整个脚本块。 All of your javascript will then break. 然后你的所有javascript都会破解。

One possible solution is to check for </script> when passing the template data to the template, but I feel like there is a better way. 一种可能的解决方案是在将模板数据传递给模板时检查</script> ,但我觉得有更好的方法。

Safely insert the JSON as a string, and then call JSON.parse on it 安全地将JSON作为字符串插入,然后在其上调用JSON.parse

Use escapejs instead of safe. 使用escapejs而不是安全。 It is designed for outputting to JavaScript. 它专为输出到JavaScript而设计。

var the_json = '{{my_json|escapejs}}';

To get a JavaScript object you then need to call JSON.parse on that string. 要获取JavaScript对象,您需要在该字符串上调用JSON.parse This is always preferable than dumping a JSON-encoding into your script and evaluating it directly, for security reasons. 出于安全原因,这总是比将JSON编码转储到脚本并直接评估它更好。

A useful filter to get python objects directly to the client that I use is this: 一个有用的过滤器将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=(',', ':'))))

And use it like: 并使用它像:

var Settings = {{ js_settings|to_js }};

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM