如何在HTML文档中安全地使用嵌入JSON?
在Rails 3.1应用程序中,如何安全地将一些JSON数据嵌入到HTML文档中?
假设我在控制器操作中有这个:
@tags = [ {name:"tag1", color:"green"}, {name:"I can do something bad here", color:"red"} ]
这在相应的观点中:
//<![CDATA[ var tags_list = ; // ]]>
然后我得到这个结果HTML:
var tags_list = [ {"name":"tag1","color":"green"}, {"name":"</script><b>I can do something bad here</b>","color":"red"} ];
这会在Chrome中触发SyntaxError: Unexpected token &
如果我使用删除Rails的默认HTML转义,则返回以下内容:
var tags_list = [ {"name":"tag1","color":"green"}, {"name":"I can do something bad here","color":"red"} ];
当然,它使用打破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返回的字符串安全,并且仍然可以正确地解析它。
更新:根据@coreyward评论,我确实把它变成了一个JS字符串文字,现在看起来效果很好。 它不像我希望的那样优雅的解决方案,但也不是太糟糕。 这是适合我的代码:
<% tags = [{name:"tag1", color:"green"}, {name:"I can \n\ndo something bad here", color:"red"}] %> //<![CDATA[ var tags_list = $.parseJSON(''); // ]]>
这导致:
//<![CDATA[ var tags_list = $.parseJSON('[{\"name\":\"tag1\",\"color\":\"green\"},{\"name\":\"I can \\n\\ndo something bad here\",\"color\":\"red\"}]'); // ]]>
使用@tags.to_json
代码在@tags.to_json
工作, 如果你启用它:
ActiveSupport.escape_html_entities_in_json = true
否则,你的另一个选择是:
var tags_list = <%= raw @tags.to_json.gsub("", "<\\/") %>;
这节省了客户端必须通过$解析整个事情
顺便说一句,这可行,但在我看来并不是一个好的解决方案:
我想如果你试试这个会起作用:
var tags_list = "<%== @tags.to_json.gsub('/', '\/') %>";
(注意双==和“”)