Note that there are some explanatory texts on larger screens.

plurals
  1. POHow to safely embed JSON with </script> in HTML document?
    text
    copied!<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><code>@tags = [ {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>And this in a corresponding view:</p> <pre><code>&lt;script type="text/javascript" charset="utf-8"&gt; //&lt;![CDATA[ var tags_list = &lt;%= @tags.to_json %&gt;; // ]]&gt; &lt;/script&gt; </code></pre> <p>Then I get this in resulting HTML:</p> <pre><code>var tags_list = [ {&amp;quot;name&amp;quot;:&amp;quot;tag1&amp;quot;,&amp;quot;color&amp;quot;:&amp;quot;green&amp;quot;}, {&amp;quot;name&amp;quot;:&amp;quot;&amp;lt;/script&amp;gt;&amp;lt;b&amp;gt;I can do something bad here&amp;lt;/b&amp;gt;&amp;quot;,&amp;quot;color&amp;quot;:&amp;quot;red&amp;quot;} ]; </code></pre> <p>which triggers a <code>SyntaxError: Unexpected token &amp;</code> in Chrome</p> <p>If I remove the Rails' default HTML escaping with <code>&lt;%=raw tags.to_json %&gt;</code>, then it returns this:</p> <pre><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>which, of course, breaks the HTML document with <code>&lt;/script&gt;</code>.</p> <p>Can I somehow tell to_json() method to return something more like this:</p> <pre><code>var tags_list = [ {"name":"tag1","color":"green"}, {"name":"&amp;lt;/script&amp;gt;&amp;lt;b&amp;gt;I can do something bad here&amp;lt;/b&amp;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><code>&lt;% tags = [{name:"tag1", color:"green"}, {name:"&lt;/script&gt;&lt;b&gt;I can \n\ndo something bad here&lt;/b&gt;", color:"red"}] %&gt; &lt;script type="text/javascript" charset="utf-8"&gt; //&lt;![CDATA[ var tags_list = $.parseJSON('&lt;%=j tags.to_json.html_safe %&gt;'); // ]]&gt; &lt;/script&gt; </code></pre> <p>which results in:</p> <pre><code>&lt;script type="text/javascript" charset="utf-8"&gt; //&lt;![CDATA[ var tags_list = $.parseJSON('[{\"name\":\"tag1\",\"color\":\"green\"},{\"name\":\"&lt;\/script&gt;&lt;b&gt;I can \\n\\ndo something bad here&lt;\/b&gt;\",\"color\":\"red\"}]'); // ]]&gt; &lt;/script&gt; </code></pre>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload