2011-11-22 78 views
2

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

回答

0

原来这是Ruby的“json”gem中的一个错误。我已经位于GitHub上的来源,发现这个pull请求坐在队列:

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

的解决方案是为了躲避正斜杠,导致JSON这样的:

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

谢谢为了您的所有帮助,我希望这个解决方案能够帮助别人!

0

如果您认为这是浏览器的问题,那么请显示结果标记,而不是红宝石。

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

+0

我已根据您的评论更新了该问题。我考虑过Base64,但在我的丑陋解决方案中使用了html编码。它达到了相同的结果,但仍然感觉我错了:( –

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); 
    } 
}); 

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

+1

这是一个不错的主意,但为什么两个请求可以在一个时间完成? –

相关问题