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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/14290517/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-26 21:14:35  来源:igfitidea点击:

Safely Using JSON with html inside of the JSON in Django Templates

javascriptpythonhtmldjango

提问by speedplane

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. The JSON occasionally contains snippets of 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.

在 django 的服务器上,我生成 JSON 数据,然后在 django 模板中呈现该 JSON 数据。JSON 偶尔包含 html 片段。大多数情况下,这很好,但是如果</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 htmlworks 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. All of your javascript will then break.

JSON 代码中的关闭脚本标记被视为关闭整个脚本块。然后你所有的 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>何时将模板数据传递给模板,但我觉得有更好的方法。

回答by Flash

Safely insert the JSON as a string, and then call JSON.parse on it

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

Use escapejsinstead of safe. It is designed for outputting to JavaScript.

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

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

To get a JavaScript object you then need to call JSON.parseon that string. This is always preferable than dumping a JSON-encoding into your script and evaluating it directly, for security reasons.

要获取 JavaScript 对象,您需要调用JSON.parse该字符串。出于安全原因,这总是比将 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 }};