2011-11-22 74 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

這是一個不錯的主意,但爲什麼兩個請求可以在一個時間完成? –

相關問題