安全地将Ruby对象传递给JavaScript

时间:2011-11-22 23:16:14

标签: javascript ruby json

我有一个包含用户生成的字符串的Ruby哈希。我需要将此哈希传递给JavaScript,以便进行处理。我已经尝试过使用JSON,它大部分时间都在工作,但是当哈希包含文本</script>时会中断。这是Chrome和FF8中最简单的代码:

<%
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,取消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实体。

3 个答案:

答案 0 :(得分:0)

如果您认为浏览器存在问题,请显示生成的标记,而不是红宝石。

我在过去通过base64编码服务器端的json解决了类似的问题。然后解码它并在客户端json.parsing它。

答案 1 :(得分:0)

是否有任何理由不再向服务器执行另一次回调以在另一个请求中获取JSON,如下所示:

var foo;
jQuery.get('/your_controller/' + resource_id + '/controller_action.json', null, function(data) {
    try {
     foo = data
    } catch (e) {          
      console.log("Error get data: " + e.message);
    }
 });

我真的不知道您的应用程序是什么,但这是一个有效的选项。

答案 2 :(得分:0)

事实证明这是Ruby的“json”gem中的一个错误。我在GitHub上找到了源代码,发现这个拉取请求位于队列中:

https://github.com/flori/json/pull/51

解决方法是转义正斜杠,产生如下JSON:

{"foo":"<\/script>"}

感谢您的帮助,我希望此解决方案可以帮助其他人!