在jinja2中转义引号

24

我正在jinja文件中构建一个JSON对象:

object_name = {
    property_name: "{{ _("Some Text which might have "quotes" in it")  }}"
}

然后在脚本标签中导入上述jinja2文件。

注意:_("Text")用于将其替换为翻译文本,因此小括号中的文本将被另一种语言的文本替换,因此我无法预测翻译是否会包含双引号。

有什么办法可以转义传入的引号并将它们转换为例如"之类的字符吗?

编辑

解决方案:

我们解决这个问题的方法是让Python处理所有的翻译并转义所有引号。但我们始终必须确保至少英文文本不会出现问题,无论如何,我们都可以控制......迄今为止 :)

也可以查看此文档

http://pology.nedohodnik.net/doc/user/en_US/ch-poformat.html#sec-poescapes

5个回答

17

Jinja2从2.9版本开始具有很好的过滤器tojson。如果您将字符串转换为json,它将生成用双引号""包含的字符串。您可以在javascript中安全地使用它,而且不需要自己添加引号。

string = {{ html_string|tojson }};

在您的情况下,可能更容易在Python中创建字典,然后使用一次转换为Javascript对象。
jsObject = {{ py_dict|tojson }};

tojson 函数会转义引号 ",并且通过转义一些重要的符号如 <>&' 来防止 XSS 攻击。在 jinja 2.10 上进行过测试。

t = jinja2.Template('{{s|tojson}}')
r = t.render(s="""</script>"...'""")
print(r) # "\u003c/script\u003e\"...\u0027"

1
关于“你可以在JavaScript中安全使用它”的说法,要小心,这并不完全正确。如果输入字符串包含</script>,即使它在引号内部,浏览器也会将其解释为结束HTML标签!在其后添加另一个<script>,你就会得到一个漂亮的XSS攻击。除了替换</script>之外,我没有更好的解决方案。 - johndodo
我的当前的jinja2(2.10)将其呈现为“\u003c/script\u003e”。这是安全的。 - Alexander C

10

flask 中,有一个名为 tojson 的默认过滤器可以使用,或者在纯 jinja2 中,您可以创建自己的 tojson 过滤器:

>>> import json
>>> env = jinja2.Environment()
>>> env.filters['tojson'] = json.dumps
>>> tmpl = env.from_string("""\
object_name = {
    property_name: {{ _(text)|tojson  }}
}""")
>>> print tmpl.render({'_': lambda x: x, 'text': 'Some text with "Quotes"'})
object_name = {
    property_name: "Some text with \"Quotes\""
}

1
tojson is great. Had a list of objects, which I needed as json array. tags | map(attribute='title') | list | tojson - luckydonald

4
没有清楚地理解问题。如果使用单个反斜杠转义无效,则需要使用反斜杠进行转义。请按如下格式翻译:

没有清楚地理解问题。如果使用单个反斜杠转义无效,则需要使用反斜杠进行转义。

object_name = {
    property_name: "{{ _(\\\"Some Text which might have \\\"quotes\\\" in it\\\")  }}"
}

1
是的,使用反斜杠进行转义是可行的,但英文文本将自动替换为例如法语文本,我们永远不知道该法语文本中是否有引号。 - Razmig

2
过滤器是按顺序应用的,因此如果您有一个变量sometext中包含文本,您可以进行如下操作:sequentially
{{sometext|replace('"',"'")|safe}}

这将在将字符串标记为安全之前应用 replace。请记住,为了避免漏洞,您必须信任字符串的来源。

1
如果你需要在JavaScript中转义HTML,jinja2还有escape过滤器。它将&、<、>、'和"转换为实体,这样你就可以在提示中编辑HTML代码。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接