安全地将Ruby对象传递给JavaScript

Safely pass Ruby object to JavaScript

本文关键字:JavaScript 对象 Ruby 安全      更新时间:2023-09-26

我有一个包含用户生成字符串的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实体。

如果您认为这是浏览器的问题,请显示结果标记,而不是ruby。

我已经解决了类似的问题在过去的base64编码json在服务器端。然后解码它和json。在客户端解析它

您是否有理由不对服务器进行另一次回调以在另一个请求中获取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);
    }
 });

我真的不知道你的应用程序是什么,但这是一个可行的选项

原来这是Ruby的"json" gem中的一个bug。我已经在GitHub上找到了源代码,并发现这个拉请求坐在队列中:

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

解决方案是转义正斜杠,导致JSON如下:

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

谢谢你的帮助,我希望这个解决方案能帮助别人!