使用Jinja2转义JavaScript的字符串?

mes*_*shy 21 javascript python jinja2

如何使用Jinja2转义HTML,以便它可以在JavaScript(jQuery)中用作字符串?

如果我使用Django的模板系统,我可以写:

$("#mydiv").append("{{ html_string|escapejs }}");
Run Code Online (Sandbox Code Playgroud)

Django的|escapejs过滤器会逃避html_string(例如引号,特殊字符)可能会破坏此代码块的预期用途的东西,但Jinja2似乎没有等效的过滤器(我在这里错了吗?).

有没有比从Django复制/粘贴代码更清晰的解决方案?

Tom*_*zky 15

这是一个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
Run Code Online (Sandbox Code Playgroud)

模板中的安全使用示例:

<script type="text/javascript">
<!--
var variableName = "{{ variableName | escapejs }}";
…
//-->
</script>
Run Code Online (Sandbox Code Playgroud)

当variableName是a strunicode.时.

  • 这个答案帮助我解决了这个问题.真正的思想弯曲者可以转义字符串中的字符,这些字符将从Python打印到HTML,这将是JavaScript内部的引用标记,它将作为JSON进行解析.Thnx的帮助! (2认同)

ron*_*man 9

去年我遇到了类似的问题.不确定你是否使用瓶子,但我的解决方案看起来像这样.

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}})
Run Code Online (Sandbox Code Playgroud)

(我将template_settingsdict 包装在辅助函数中,因为我到处都使用它,但在这个例子中我保持简单.)

不幸的是,它并不像内置的jinja2过滤器那么简单,但我能够愉快地使用它 - 特别是考虑到我还要添加其他几个自定义过滤器.

重要提示:下面给@ medmunds提供精明的评论,提醒我们json.dumps不是XSS安全的.IOW,您不希望在面向互联网的生产服务器中使用它.建议是写一个更安全的json转义程序(或者偷django的 - 抱歉OP,我知道你希望避免这种情况)并调用它而不是使用json.dumps.

  • 我不认为json.dumps()会逃避你需要担心的一切.例如,正如当前所写,`escapejs("</ script>")`返回`"</ script>"` - 这似乎可以允许关闭脚本标记(及其后的任何内容!)泄漏到您的html中.(Django escapejs过滤器对<和>字符进行unicode转义,避免了这个问题.) (8认同)

Ale*_*hen 8

Jinja2具有不错的tojson过滤器。如果从字符串制作json,它将生成用双引号“”括起来的字符串。您可以在javascript中安全地使用它。而且您不需要自己加上引号。

$("#mydiv").append({{ html_string|tojson }});
Run Code Online (Sandbox Code Playgroud)