【发布时间】:2011-11-04 13:48:28
【问题描述】:
在 Rails 3.1 应用程序中,如何安全地将一些 JSON 数据嵌入到 HTML 文档中?
假设我在控制器动作中有这个:
@tags = [
{name:"tag1", color:"green"},
{name:"</script><b>I can do something bad here</b>", color:"red"}
]
在相应的视图中:
<script type="text/javascript" charset="utf-8">
//<![CDATA[
var tags_list = <%= @tags.to_json %>;
// ]]>
</script>
然后我在生成的 HTML 中得到这个:
var tags_list = [
{"name":"tag1","color":"green"},
{"name":"</script><b>I can do something bad here</b>","color":"red"}
];
在 Chrome 中触发 SyntaxError: Unexpected token &
如果我使用<%=raw tags.to_json
%> 删除 Rails 的默认 HTML 转义,那么它会返回:
var tags_list = [
{"name":"tag1","color":"green"},
{"name":"</script><b>I can do something bad here</b>","color":"red"}
];
当然,它会使用</script> 破坏 HTML 文档。
我能不能告诉 to_json() 方法返回类似这样的东西:
var tags_list = [
{"name":"tag1","color":"green"},
{"name":"</script><b>I can do something bad here</b>","color":"red"}
];
我在 rubyonrails-talk 邮件列表上提出了这个问题,我现在明白有些人认为一开始这是一个非常糟糕的主意,但就我而言,只要没有 HTML 特殊字符,它就可以很好地工作数据。所以我只想让to_json HTML 返回的字符串安全,并且仍然让 JavaScript 正确解析它。
更新: 根据@coreyward 的评论,我确实把它变成了一个 JS 字符串文字,现在看起来效果很好。它不像我希望的那样优雅,但也不算太糟糕。这是对我有用的代码:
<% tags = [{name:"tag1", color:"green"}, {name:"</script><b>I can \n\ndo something bad here</b>", color:"red"}] %>
<script type="text/javascript" charset="utf-8">
//<![CDATA[
var tags_list = $.parseJSON('<%=j tags.to_json.html_safe %>');
// ]]>
</script>
导致:
<script type="text/javascript" charset="utf-8">
//<![CDATA[
var tags_list = $.parseJSON('[{\"name\":\"tag1\",\"color\":\"green\"},{\"name\":\"<\/script><b>I can \\n\\ndo something bad here<\/b>\",\"color\":\"red\"}]');
// ]]>
</script>
【问题讨论】:
-
包含在 JS 字符串文字中的 HTML 不应影响页面的呈现。它应该像字符串中的任何其他字符一样对待。当您使用
raw tags.to_json时,您可能想要调查真正发生了什么。 -
您正在将 JSON 包装在
<script>标签中,对吗?只要它在脚本中,HTML 就会被忽略...相信我,您可以在脚本中包含一个 JS 字符串,该脚本具有有效标签的整个页面(<html><head>.. 等),它不会弄乱渲染。 -
我的问题中的第二个代码 sn-p 是我如何将它嵌入到 HTML 页面中。所以它在
<script>标签内,而不是在字符串文字内,而是像原始 JS 对象一样。只要@tags变量中没有 HTML 特殊字符,这就会很好地工作。 -
@coreyward 你给了我一个想法,我可以让它成为有效的 JS 字符串并用 jQuery 解析它,这实际上让我找到了一个我相当满意的解决方案。感谢那! :) 所以我现在不是在做
var tags_list = <%= @tags.to_json %>;,而是在做var tags_list = $.parseJSON('<%=j tags.to_json.html_safe %>');,这让我的工作做得足够好。最初我想在 HTML 中将它作为普通的 JS 对象/哈希,但我宁愿让 jQuery 进行解析,然后我在服务器上为每个对象进行适当的 HTML 转义。这对我来说似乎更通用。 -
下面的赏金消息应该是:在直接嵌入到 Rails 视图中的 JSON 中,真的没有标准的转义
"</script>"字符串的方法吗?
标签: ruby-on-rails json ruby-on-rails-3 html-parsing