How to pass data to Javascript variable from Ruby on Rails

I wonder on RoR, will there be a need sometimes to pass some data from Ruby to Javascript?

1) var title = ______________ ;

What is the proper way to do it (fill in the code for ______________ ) if title can have newline character, or single / double quote or any weird character. and what's more, what if the title from database can have <script> tags, so the code need to do cross-site scripting (xss) prevention, say, if the title needs to be set into a div's innerHTML later.

2) further more, what if we do

<a href="#" onclick="changeIt(______________); return false;">Click me</a>

This case is more complicated, since I think there is a rule that says, anything inside the attribute's value will first be parsed by the browser as HTML first, so this is a little trickier than case (1).

Any standard way in Rails to do it? Thanks.

The most straightforward way of doing what you want is: <%= my_var %>

Chris Kottom wrote:

The most straightforward way of doing what you want is: <%= my_var %>

On Wed, Apr 8, 2009 at 7:31 AM, SpringFlowers AutumnMoon <

are you sure? if my_var contains a newline character, then the Javascript code becomes

var title = hello world;

and it will break? sorry i haven't used RoR for a long time so don't know if any quote is given for <%= my_var %>

SpringFlowers AutumnMoon wrote:

I wonder on RoR, will there be a need sometimes to pass some data from Ruby to Javascript?

1) var title = ______________ ;

<script type="text/javascript" charset="utf-8">   var title = '<%= h @my_var -%>' </script>

What is the proper way to do it (fill in the code for ______________ ) if title can have newline character, or single / double quote or any weird character. and what's more, what if the title from database can have <script> tags, so the code need to do cross-site scripting (xss) prevention, say, if the title needs to be set into a div's innerHTML later.

2) further more, what if we do

<a href="#" onclick="changeIt(______________); return false;">Click me</a>

This case is more complicated, since I think there is a rule that says, anything inside the attribute's value will first be parsed by the browser as HTML first, so this is a little trickier than case (1).

<a href="#" onclick="changeIt('<%= h @my_var -%>'); return false;">Click me</a>

However, I think you're right about the format of the string object. HTML escape won't provide what you want so you probably need to write your own sanitizing helper and use that in place of html_escape (h) helper. A quick-and-dirty one I came up with was my_var.gsub(/[\n\'\"<>]/, ""). I'm sure that's probably not comprehensive, but does seem to take care of the issues mentioned here.

SpringFlowers AutumnMoon wrote: me</a>

However, I think you're right about the format of the string object. HTML escape won't provide what you want so you probably need to write your own sanitizing helper and use that in place of html_escape (h) helper. A quick-and-dirty one I came up with was my_var.gsub(/[\n\'\"<>]/, ""). I'm sure that's probably not comprehensive, but does seem to take care of the issues mentioned here.

I normally use to_json

Fred

Frederick Cheung wrote:

SpringFlowers AutumnMoon wrote:

i think to_json is more like a transition to the Javascript realm... however, isn't it true that if we ever need to set the title into the div's innerHTML, then we also need to sanitize it?

so to_json(h(title)) ?

and is there something like

to_json(strip_tags(title)) ? i think this one always works and just remove any tag from the title.

SpringFlowers AutumnMoon wrote: [...]

however, isn't it true that if we ever need to set the title into the div's innerHTML, then we also need to sanitize it?

so to_json(h(title)) ?

Actually, that would be h(to_json title). Remember, you put it into JSON first, then escape it for HTML so it won't break the DOM.

Best,

by the way, sanitize and strip_tags work as follows:

<div id="divForS"></div> <div id="divForT"></div>

<script type="text/javascript"> var v = 1;

var s = <%= sanitize(@s).to_json %>;

var t = <%= strip_tags(@s).to_json %>;

document.getElementById('divForS').innerHTML = s + v; document.getElementById('divForT').innerHTML = t + v; </script>

the HTML generated is:

var s = "Bill Gates's dog said \"whoof whoof\" and \n \074b\076ran\074/b\076 &lt;script\076 alert('hi');v=2; &lt;/script\076 away.";

var t = "Bill Gates's dog said \"whoof whoof\" and \n ran alert('hi');v=2; away.";

and the web browser shows it as on the screen:

Bill Gates's dog said "whoof whoof" and ran <script> alert('hi');v=2; </script> away.1 Bill Gates's dog said "whoof whoof" and ran alert('hi');v=2; away.1

one thing i don't understand is that if i remove the sanitize function, the alert will not get called, and v won't be set to 2, so the line for innerHTML = t + v will still show v as 1. I thought the script part will get executed? Or is it a rule that it won't be executed and in that case, we don't need to use h, sanitize, or strip_tags to prevent cross-site scripting (XSS) if we set the value into innerHTML? So in that case, s.to_json is good enough? (unless if some browser actually execute them, and make XSS possible). thanks.

SpringFlowers AutumnMoon wrote: [...]

then the code generated is

<script type="text/javascript">

  var s = &quot;Bill Gates's dog said \&quot;whoof whoof\&quot; and \n ran away.&quot;;

  var t = "Bill Gates's dog said &quot;whoof whoof&quot; and \n ran away.";

</script>

Sorry, I misunderstood what you were trying to do. If you are putting dynamically generated JavaScript in an HTML file, wrap the script in a CDATA section and don't HTML-escape it

However, putting JS in HTML files is a bad idea for lots of reasons, and you should never need to do so. Better to use an external JS file that contains lines like var s = document.getElementById('s').innerHTML

and then have your view contain

<div id='s'><%=h my_string%></div>

Best,