16

I've tried everything. Every combination of the helpers raw, html_safe to_json including some attempts with ::JSON.encode and CGI.unescape. The issue is that regardless of what I do, I can't print well-formed JSON in a view. It's always HTML escaped.

Here's the code in my view:

var campaignData<%= "=" + (raw @campaign.to_json) if @campaign %>;

In my case, it's always the quotes that are escaped as ". I would just do a gsub on the quotes, but that is a terrible solution to what IMO ought to be a very simple, well documented use case.

4 Answers 4

33
+50

The problem here is with the "=" string. As it's considered unsafe, it taints the other string.

You can probably do either:

raw("=" + @campaign.to_json)

or

"= #{@campaign.to_json}".html_safe

which are roughly the same.

Sign up to request clarification or add additional context in comments.

2 Comments

This is unsafe. What if the json contains a string with a less-than? If you put this in a script tag, someone can inject a closing script tag and start a new one with arbitrary code. You need to wrap the json string in json_escape. However, that function has been broken until just recently (rails 4.1).
Yes, I too found that this did not work for me when @campaign == "<script>alert('pwn')</script>"
15

Since ActiveSupport 2.3.3 you have been able to do .as_json

Comments

5

Did you try escape_javascript?

Here is an example from the *.haml file, which I just added to test my answer.

:javascript
  var foo=$.parseJSON("#{j @albums.to_json}")

Where j is an short alias for escape_javascript.

4 Comments

Yea, that didn't work. Right now I'm just manually printing each value that I need, which is an awful solution, but its the only way I've been able to make it work.
Could you paste here a bit of your escaped string? Also, which version of ruby and rails do you use? Just wondering what could be wrong with that
It was valid JSON, except the quotes were replaced with the HTML quote entity &quot; Using Rails 3.2.1
This was the best solution for me. I already have a model that returns valid JSON, but characters like \u2028 won't parse if included in the bootstrapped HAML.
0

Try this with utility method

var campaignData<%=h " =#{raw @campaign.to_json}" if @campaign %>;

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.