Как в приложении 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>