How to safely embed JSON object in HTML document

Hi all,

I’m working on a Backbone.js single page app with Rails 3.1, and in an
attempt to save on HTTP requests, I want to embed initial data set in
a HTML document that is sent back to the browser after successful
login.

I was thinking I can simply convert my ruby object to JSON, then HTML
escape resulting string of JSON, and then use that as a value for
JavaScript variable. Something like this:

<% tags = [{name:“tag1”, color:“green”}, {name:“I can do
something bad here
”, color:“red”}] %>

However, this escapes all the double quotes in that string, which
triggers a “SyntaxError: Unexpected token &” in Chrome:

var tags_list =
[{"name":"tag1","color":"green"},
{"name":"</script><b>I can do something bad
here</b>","color":"red"}];

If I remove the Rails’ default HTML escaping with <%=raw tags.to_json
%>, then it returns this:
var tags_list = [{“name”:“tag1”,“color”:“green”},{“name”:"</
script>I can do something bad here",“color”:“red”}];

which, of course, breaks the HTML document with “”.

I guess what I really want is to tell to_json() method to HTML escape
keys and values inside JSON object(s), instead of it returning the
JSON string unescaped, and then having Rails escape that whole string.
I guess what I need is something like this:

var tags_list = [{“name”:“tag1”,“color”:“green”},{“name”:"</
script><b>I can do something bad here</
b>",“color”:“red”}];

I thought about storing JSON string in a tag, and then doing something like

$.parseJSON($("#json_string").html())

but that also has the same problem of escaping, like in the above
example.

Is there any easy (Rails) way to do that? Or am I doing it wrong to
begin with?

Cheers!

Hi Alex,

What is it that you’re actually trying to do? I don’t think its such a
good
idea to put a JSON string on the client side as it can be manipulated to
no
end.

Why not just call the JSON object directly from the controller instead?

David
@davidchua

David,

I want to embed it in HTML so that I can just send that one HTML page to
user after log in, and no other HTTP requests are needed before the user
can
start using the app.
This is because it would take several small, but slow, HTTP requests to
gather all the data that is needed to show the page. I guess I could
whip up
a special API method that would return all the data in a single HTTP
roundtrip, but if I can pull off this JSOPN embedding, then I can skip
even
that one extra HTTP requests for initial load. After initial load, app
will
rarely be needing data from the server, and when it does, it will be
using
regular API to get that data.

This is all just a performance optimization, since most of our users are
on
a high latency network (mobiles), so those HTTP requests really take a
while, and this is an attempt to just skip them altogether.

Is there no easy way to embed HTML safe JSON in an HTML document, and
have
it parsed by JavaScript engine at the same time?

Thanks,
Alex

I have no idea why embedded json would be considered worse than the
rest of the page that is sent down. I do it all the time, usually with
small items though, so I haven’t have the problem you are describing.
I was hoping that someone would have a suggestion of a built in method
to call.

I’ve had to do this in a helper that was constructing a complicated
object, and I think this is similar to your problem:

  1. enumerate through all the parts of your object that could contain
    dangerous data and call h() on them.
  2. call raw(your_object.to_json) on the result.

It’s definitely not an easy, generic solution, but it gets you past
this problem.

The purpose of JSON is to be able to interchange the data between
various systems. As you are not going to do that then why use JSON at
all?

Honestly if you are going to process the JSON with Javascript what
dont you write your data out as Javascript data structures (which it
would be converted from JSON anyway) in the page and process that?
What do you gain from embedding the JSON then having to convert it
into Javascript data structures over just writing the native
Javascript data structures?

Alex Duck wrote in post #1018609:

Is there no easy way to embed HTML safe JSON in an HTML document, and
have
it parsed by JavaScript engine at the same time?

You could Base64 encode the JSON and decode it on the client-side with
JavaScript.

I am ABSOLUTELY NOT recommending that you do this, but simply stating
that it could work. Still a bad design idea IMHO.

Paul,

thanks for the suggestion. I was hoping there is something in Rails to
do
that for me. But I guess there isn’t.

Other suggestion I got, off this list, is to have JSON embedded in a
javascript string, and parsed by jQuery into an object. With proper
javascript escaping (by j method), that gets the job done. And I like
that
approach better then calling h on attributes on server side, as this is
more
generic IMO, since it will work for any Ruby object.

Here is the code that works:

<% tags = [{name:“tag1”, color:“green”}, {name:“I can \n\ndo
something bad here
”, color:“red”}] %>

And that results in:

Thanks all!

On Fri, Aug 26, 2011 at 4:43 PM, Peter H. <

I’m surprised that Rails doesn’t have a built-in way of doing this!
As Paul said, I can’t think of why embedded json would be worse than
any other way of transmitting the data, especially for things like
backbone apps.

As I mentioned on
http://stackoverflow.com/questions/7205902/how-to-safely-embed-json-in-html-document/
a workaround is:

but that’s kind of ugly. Again, I’m surprised there isn’t a built-in
way of passing JSON data to from controller to view like this. Am I
missing some obvious reason why?