如何在HTML文档中安全地嵌入JSON和</ script>?

在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 = [
    {&quot;name&quot;:&quot;tag1&quot;,&quot;color&quot;:&quot;green&quot;},
    {&quot;name&quot;:&quot;&lt;/script&gt;&lt;b&gt;I can do something bad here&lt;/b&gt;&quot;,&quot;color&quot;:&quot;red&quot;}
];

这会在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":"&lt;/script&gt;&lt;b&gt;I can do something bad here&lt;/b&gt;","color":"red"}
];

我在rubyonrails-talk邮件列表上问了这个问题,我现在明白,有些人认为这是一个非常糟糕的主意,但在我的情况下,它的工作原理非常好,只要数据中没有HTML特殊字符。 所以我只想让to_json HTML返回的字符串安全并且仍然可以正确解析JavaScript。

更新:基于@coreyward评论,我确实使它成为一个JS字符串文字,而且现在似乎工作得很好。 它不像我期望的那样优雅,但也不算太糟糕。 这是为我工作的代码:

<% tags = [{name:"tag1", color:"green"}, {name:"</script><b>I can nndo 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 nndo something bad here</b>","color":"red"}]');
    // ]]>
</script>

只需使用@tags.to_json代码就可以在@tags.to_json运行,如果通过以下方式启用它:

   ActiveSupport.escape_html_entities_in_json = true

否则,你的其他选择是这样的:

   var tags_list = <%= raw @tags.to_json.gsub("</", "</") %>;

这节省了客户必须通过$解析整个事情


顺便说一句,这工作,但不是在我看来很好的解决方案:

<script type="text/javascript" charset="utf-8">
  //<![CDATA[
  var tags_list = <%=raw @tags.to_json.gsub('/', '/') %>;
  // ]]>
</script>

我认为,如果你尝试这个方法,它会起作用:

var tags_list = "<%== @tags.to_json.gsub('/', '/') %>";

(注意double ==和“”)

链接地址: http://www.djcxy.com/p/47927.html

上一篇: How to safely embed JSON with </script> in HTML document?

下一篇: JSONObject.toString: how NOT to escape slashes