in HTML document?", "text": "<p>In a Rails 3.1 app, how can I safely embed some JSON data into an HTML document?</p> <p>Suppose I have this in a controller action:</p> <pre class="prettyprint"><code>@tags = [ {name:"tag1", color:"green"}, {name:"</script><b>I can do something bad here</b>", color:"red"} ] </code></pre> <p>And this in a corresponding view:</p> <pre class="prettyprint"><code><script type="text/javascript" charset="utf-8"> //<![CDATA[ var tags_list = <%= @tags.to_json %>; // ]]> </script> </code></pre> <p>Then I get this in resulting HTML:</p> <pre class="prettyprint"><code>var tags_list = [ {&quot;name&quot;:&quot;tag1&quot;,&quot;color&quot;:&quot;green&quot;}, {&quot;name&quot;:&quot;&lt;/script&gt;&lt;b&gt;I can do something bad here&lt;/b&gt;&quot;,&quot;color&quot;:&quot;red&quot;} ]; </code></pre> <p>which triggers a <code>SyntaxError: Unexpected token &</code> in Chrome</p> <p>If I remove the Rails' default HTML escaping with <code><%=raw tags.to_json %></code>, then it returns this:</p> <pre class="prettyprint"><code>var tags_list = [ {"name":"tag1","color":"green"}, {"name":"</script><b>I can do something bad here</b>","color":"red"} ]; </code></pre> <p>which, of course, breaks the HTML document with <code></script></code>.</p> <p>Can I somehow tell to_json() method to return something more like this:</p> <pre class="prettyprint"><code>var tags_list = [ {"name":"tag1","color":"green"}, {"name":"&lt;/script&gt;&lt;b&gt;I can do something bad here&lt;/b&gt;","color":"red"} ]; </code></pre> <p>I asked this question on rubyonrails-talk mailing list, and I understand now that some people think that's a very bad idea to begin with, but in my case it works very nicely, as long as there are no HTML special chars in the data. So I just want to make the string returned by <code>to_json</code> HTML safe and still have JavaScript parse it properly.</p> <p><strong>UPDATE:</strong> Based on @coreyward comment, I did make it a JS string literal, and that seems to be working great now. Its not quite as elegant of a solution as I was hoping for, but its not too bad either. Here is the code that is working for me:</p> <pre class="prettyprint"><code><% 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> </code></pre> <p>which results in:</p> <pre class="prettyprint"><code><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> </code></pre>", "answerCount": 1, "upvoteCount": 457, "dateCreated": "2011-08-26 14:08:33", "dateModified": "2022-10-24 04:13:41", "author": { "type": "Person", "name": "nnc" }, "acceptedAnswer": { "@type": "Answer", "text": "<p>Your code using just <code>@tags.to_json</code> works in rails3, <em>if</em> you enable it with:</p> <pre class="prettyprint"><code> ActiveSupport.escape_html_entities_in_json = true </code></pre> <p>Otherwise, your other option is this:</p> <pre class="prettyprint"><code> var tags_list = <%= raw @tags.to_json.gsub("</", "<\\\\/") %>; </code></pre> <p>This saves the client having to parse the whole thing through $</p>", "upvoteCount": 147, "url": "https://exchangetuts.com/how-to-safely-embed-json-with-script-in-html-document-1639810629054982#answer-1648478241128574", "dateCreated": "2022-10-22 15:13:41", "dateModified": "2022-10-24 04:13:41", "author": { "type": "Person", "name": "Lawrence Pit" } } } }