使用 Jinja2 为 JavaScript 转义字符串?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/12339806/
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
Escape strings for JavaScript using Jinja2?
提问by meshy
How do I escape HTML with Jinja2 so that it can be used as a string in JavaScript (jQuery)?
如何使用 Jinja2 转义 HTML 以便它可以用作 JavaScript (jQuery) 中的字符串?
If I were using Django's templating system I could write:
如果我使用 Django 的模板系统,我可以这样写:
$("#mydiv").append("{{ html_string|escapejs }}");
Django's |escapejs
filterwould escape things in html_string
(eg quotes, special chars) that could break the intended use of this code block, but Jinja2 does not seem to have an equivalent filter (am I wrong here?).
Django 的|escapejs
过滤器会转义html_string
(例如引号、特殊字符)中可能破坏此代码块的预期用途的东西,但 Jinja2 似乎没有等效的过滤器(我在这里错了吗?)。
Is there a cleaner solution than copying/pasting the code from Django?
有没有比从 Django 复制/粘贴代码更干净的解决方案?
采纳答案by ron rothman
I faced a similar problem last year. Not sure whether you're using bottle, but my solution looked something like this.
我去年也遇到过类似的问题。不确定您是否在使用Bottle,但我的解决方案看起来像这样。
import json
def escapejs(val):
return json.dumps(str(val)) # *but see [Important Note] below to be safe
@app.route('/foo')
def foo():
return bottle.jinja2_template('foo', template_settings={'filters': {'escapejs': escapejs}})
(I wrapped the template_settings
dict in a helper function since I used it everywhere, but I kept it simple in this example.)
(我将template_settings
dict包装在一个辅助函数中,因为我到处都使用它,但在这个例子中我保持简单。)
Unfortunately, it's not as simple as a builtin jinja2 filter, but I was able to live with it happily--especially considering that I had several other custom filters to add, too.
不幸的是,它不像内置的 jinja2 过滤器那么简单,但我能够愉快地接受它——特别是考虑到我还有其他几个自定义过滤器要添加。
Important Note: Hat tip to @medmunds's for his astute comment below, reminding us that json.dumps is not XSS-safe. IOW, you wouldn't want to use it in a production, internet-facing server. Recommendation is to write a safer json escape routine(or steal django's--sorry OP, I know you were hoping to avoid that) and call that instead of using json.dumps.
重要提示:感谢@medmunds 在下面的敏锐评论,提醒我们 json.dumps 不是 XSS 安全的。IOW,您不会希望在面向 Internet 的生产服务器中使用它。建议是编写一个更安全的 json 转义例程(或窃取 django 的——对不起,我知道你希望避免这种情况)并调用它而不是使用 json.dumps。
回答by Tometzky
This is a escapejs
filter, based on Django's one, that I wrote for use in Jinja2 templates:
这是一个escapejs
基于 Django 的过滤器,我编写用于 Jinja2 模板:
_js_escapes = {
'\': '\u005C',
'\'': '\u0027',
'"': '\u0022',
'>': '\u003E',
'<': '\u003C',
'&': '\u0026',
'=': '\u003D',
'-': '\u002D',
';': '\u003B',
u'\u2028': '\u2028',
u'\u2029': '\u2029'
}
# Escape every ASCII character with a value less than 32.
_js_escapes.update(('%c' % z, '\u%04X' % z) for z in xrange(32))
def jinja2_escapejs_filter(value):
retval = []
for letter in value:
if _js_escapes.has_key(letter):
retval.append(_js_escapes[letter])
else:
retval.append(letter)
return jinja2.Markup("".join(retval))
JINJA_ENVIRONMENT.filters['escapejs'] = jinja2_escapejs_filter
Example safe usage in a template:
模板中的安全用法示例:
<script type="text/javascript">
<!--
var variableName = "{{ variableName | escapejs }}";
…
//-->
</script>
When variableName is a str
or unicode
.
当 variableName 是 astr
或unicode
.
回答by Alexander Chzhen
Jinja2 has nice filter tojson. If you make json from string, it will generate string enclosed in double quotes "". You can safely use it in javascript. And you don't need put quotes around by yourself.
Jinja2 有很好的过滤器tojson。如果从字符串生成 json,它将生成用双引号 "" 括起来的字符串。您可以安全地在 javascript 中使用它。而且你不需要自己加上引号。
$("#mydiv").append({{ html_string|tojson }});
回答by Mike Richardson
I just researched this problem, my solution is to define a filter:
我刚刚研究了这个问题,我的解决方案是定义一个过滤器:
from flask import Flask, Markup
app = Flask(__name__)
app.jinja_env.filters['json'] = lambda v: Markup(json.dumps(v))
and in the template:
并在模板中:
<script>
var myvar = {{myvar|json}} ;
</script>
This has the nice feature that myvarcan be anything that can be JSON-serialised
这有一个很好的特性,即myvar可以是任何可以 JSON 序列化的东西
回答by Sebastian Wagner
Based on @tometzky here is my Python 3 version:
基于@tometzky,这里是我的 Python 3 版本:
_js_escapes = {
'\': '\u005C',
'\'': '\u0027',
'"': '\u0022',
'>': '\u003E',
'<': '\u003C',
'&': '\u0026',
'=': '\u003D',
'-': '\u002D',
';': '\u003B',
u'\u2028': '\u2028',
u'\u2029': '\u2029'
}
# Escape every ASCII character with a value less than 32.
_js_escapes.update(('%c' % z, '\u%04X' % z) for z in range(32))
@register.filter
def escapejs(value):
return jinja2.Markup("".join(_js_escapes.get(l, l) for l in value))
The usage is exactly the same.
用法完全一样。
回答by Tony Wickham
You can also use jinja2's autoescape
. So, for instance, you could add autoescape to your jinja2 Environment in Python:
您也可以使用 jinja2 的autoescape
. 因此,例如,您可以在 Python 中将 autoescape 添加到您的 jinja2 环境中:
JINJA_ENVIRONMENT = jinja2.Environment(
loader=jinja2.FileSystemLoader(os.path.dirname(__file__)),
autoescape=True)
Alternatively, you could use the Autoescape Extension added in Jinja 2.4 to have more control over where the autoescaping is used in the HTML. More information on this hereand example (in Google App Engine) here.
或者,您可以使用 Jinja 2.4 中添加的 Autoescape 扩展来更好地控制在 HTML 中使用自动转义的位置。此处的更多信息和示例(在 Google App Engine 中)此处。
Python:
Python:
JINJA_ENVIRONMENT = jinja2.Environment(
loader=jinja2.FileSystemLoader(os.path.dirname(__file__)),
extensions=['jinja2.ext.autoescape'])
HTML:
HTML:
{% autoescape true %}
<html>
<body>
{{ IWillBeEscaped }}
</body>
</html>
{% endautoescape %}