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,