如何将嵌套字典返回到金字塔中的Mako模板?

Vit*_*mar 2 python pyramid

当我试图将嵌套字典返回到Mako模板时,它用HTML代码替换单引号'(我在浏览器的源代码中看到它).

在视图中:

@view_config(route_name='main', renderer='myproj:templates/main.mako')
def main_view(request):
    info = {'name': 'Some', 'age': 20}
    return {'info': info, 'country': 'Ukraine'}
Run Code Online (Sandbox Code Playgroud)

在Mako:

<script type="text/javascript">func(${info})</script>
Run Code Online (Sandbox Code Playgroud)

在浏览器的源代码中:

<script type="text/javascript">func({&#39;name&#39;: &#39;Some&#39;, &#39;age&#39;: 20})</script>
Run Code Online (Sandbox Code Playgroud)

如何避免这种逃避?(renderer='json'不是变种,因为我需要Mako中的字典)

Mic*_*kel 6

默认情况下,Mako配置为转义字符串.如果要禁用过滤器,可以通过此方式完成|n.具体${info|n}.

但是,在您的示例中,您尝试将python字典传递给javascript函数.这显然没有加起来,你需要将python dict变成javascript可用的东西.你真正想要做的是将你的python dict变成一个字符串,然后输出而不过滤你的javascript代码.

这可能是漂亮的,但想法是在python中你做:

@view_config(route_name='main', renderer='myproj:templates/main.mako')
def main_view(request):
    info = json.dumps({'name': 'Some', 'age': 20})
    return {'info': info, 'country': 'Ukraine'}
Run Code Online (Sandbox Code Playgroud)

在mako你做:

<script type="text/javascript">func(${info|n})</script>
Run Code Online (Sandbox Code Playgroud)

默认情况下,Pyramid设置mako使用h过滤器,它会逃避一切(你看到的问题).您可以编辑默认过滤器,但由于其他代码中可能存在副作用,因此通常不是最好的主意.另一种可能性是依靠dict的__str__实现来产生有效的javascript代码.在这种情况下,您不需要序列化任何东西,只需运行${info|str,n}(至少在这种情况下)产生您想要的结果.

  • 更新的答案,我查看了 django-mako 的实现,它对 dicts 没有做任何特别的事情(金字塔也没有)。django-mako 默认不开启转义,这对任何可能显示用户输入的人来说都是危险的(XSS 漏洞)。 (2认同)
  • 最好这样做:`json.dumps({'name': 'Some', 'age': 20}).encode('string-escape')`; 如果 json 有效负载中有任何包含单引号的文本,它将破坏 javascript。 (2认同)