我有一个包含用户生成的字符串的Ruby哈希。我需要将这个散列传递给JavaScript,以便它可以被处理。我曾尝试使用JSON,它在大多数情况下都是有效的,但是当哈希包含文本</script>
时会中断。下面是在Chrome和FF8打破了简单的代码:安全地将Ruby对象传递给JavaScript
<%
obj = {
:foo => '</script>'
}
%>
<script type="text/javascript">
var obj = <%= obj.to_json %>; // Results in JS syntax error
</script>
这将导致以下HTML:
<script type="text/javascript">
var obj = {"foo":"</script>"};
</script>
我自己也尝试在引号(单,双)包装的JSON所以可以通过jQuery.parseJSON()
解析,但它会导致同一个语法错误:
<%
obj = {
:foo => '</script>'
}
%>
<script type="text/javascript">
var json = '<%= obj.to_json %>'; // Again results in JS syntax error
</script>
看来,语法错误是浏览器的结果,试图解释</script>
文本作为脚本块的结尾。我目前的解决方案是为了躲避JSON字符串作为HTML,逃避其余反斜杠,将其写入到JS作为一个字符串,UNESCAPE的HTML,然后最后解析JSON:
<%
obj = {
:foo => '</script>'
}
json = obj.to_json
escaped_json = CGI.escapeHTML(json)
slashed_escaped_json = escaped_json..gsub(/['"\\\x0]/,'\\\\\0')
%>
<script type="text/javascript">
var json = "<%= slashed_escaped_json %>";
json = $('<div/>').html(json).text(); // unescape HTML
var obj = jQuery.parseJSON(json); // parse JSON safely
console.log(obj);
</script>
它的工作原理,但它的丑陋。有没有更好的办法?我不想去掉</script>
,因为我在将内容呈现在页面上之前,将内容转义为HTML实体。
我已根据您的评论更新了该问题。我考虑过Base64,但在我的丑陋解决方案中使用了html编码。它达到了相同的结果,但仍然感觉我错了:( –