В приложении Rails 3.1, как я могу безопасно вставлять некоторые данные JSON в HTML-документ?
Предположим, что у меня это в действии контроллера:
@tags = [
{name:"tag1", color:"green"},
{name:"</script><b>I can do something bad here</b>", color:"red"}
]
И это в соответствующем представлении:
<script type="text/javascript" charset="utf-8">
//<![CDATA[
var tags_list = <%= @tags.to_json %>;
// ]]>
</script>
Затем я получаю это в результате HTML:
var tags_list = [
{"name":"tag1","color":"green"},
{"name":"</script><b>I can do something bad here</b>","color":"red"}
];
который запускает SyntaxError: Unexpected token &
в Chrome
Если я удаляю HTML-эскиз по умолчанию Rails с помощью <%=raw tags.to_json
%>
, он возвращает это:
var tags_list = [
{"name":"tag1","color":"green"},
{"name":"</script><b>I can do something bad here</b>","color":"red"}
];
который, разумеется, разбивает HTML-документ на </script>
.
Могу ли я каким-то образом сказать to_json(), чтобы вернуть что-то более похожее на это:
var tags_list = [
{"name":"tag1","color":"green"},
{"name":"</script><b>I can do something bad here</b>","color":"red"}
];
Я задал этот вопрос в списке рассылки rubyonrails-talk, и теперь я понимаю, что некоторые люди думают, что для начала очень плохая идея, но в моем случае это работает очень хорошо, если в HTML нет специальных символов данные. Поэтому я просто хочу, чтобы строка, возвращаемая с помощью to_json
HTML, была в безопасности, и JavaScript все равно правильно ее разбирает.
UPDATE: Основываясь на комментарии @coreyward, я сделал это строковым литералом JS, и теперь он отлично работает. Это не так элегантно, как я надеялся, но это тоже неплохо. Вот код, который работает для меня:
<% tags = [{name:"tag1", color:"green"}, {name:"</script><b>I can \n\ndo something bad here</b>", color:"red"}] %>
<script type="text/javascript" charset="utf-8">
//<![CDATA[
var tags_list = $.parseJSON('<%=j tags.to_json.html_safe %>');
// ]]>
</script>
что приводит к:
<script type="text/javascript" charset="utf-8">
//<![CDATA[
var tags_list = $.parseJSON('[{\"name\":\"tag1\",\"color\":\"green\"},{\"name\":\"<\/script><b>I can \\n\\ndo something bad here<\/b>\",\"color\":\"red\"}]');
// ]]>
</script>