How to pass data to Javascript variable from Ruby on Rails


#1

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 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.

  1. further more, what if we do

Click
me

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.


#2

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

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


#3

Chris K. 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 %>


#4

SpringFlowers AutumnMoon wrote:

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 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.

  1. further more, what if we do

Click
me

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).

Click
me

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.


#5

Frederick C. wrote:

On Apr 8, 6:00�pm, Robert W. removed_email_address@domain.invalid
wrote:

SpringFlowers AutumnMoon wrote:
me

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

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)) ?


#6

On Apr 8, 6:00 pm, Robert W. removed_email_address@domain.invalid
wrote:

SpringFlowers AutumnMoon wrote:
me

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


#7

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.


#8

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,

Marnen Laibow-Koser
http://www.marnen.org
removed_email_address@domain.invalid


#9

SpringFlowers AutumnMoon 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.

sanitize is the one that can be used.


#10

Marnen Laibow-Koser wrote:

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.

hm, if i use in the app_controller.rb

class AppController < ApplicationController
def index
@s = “Bill Gates’s dog said “whoof whoof” and \n ran away.”
end
end

and then in index.rhtml, use

then the code generated is

so the first line gave an error in Firefox. I just wonder how come
something so basic but there is no general discussion in book to talk
about how to do it and some experienced developers i talked to wasn’t
sure how to do it either? By the way, so to_json is a method but h is a
function? Is there a way to write something like @s.h.to_json or
@s.to_h.to_json or @s.html_escape.to_json so that it is OO all the way?
thanks.


#11

by the way, sanitize and strip_tags work as follows:

the HTML generated is:

var s = “Bill Gates’s dog said “whoof whoof” and \n
\074b\076ran\074/b\076 <script\076 alert(‘hi’);v=2; </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 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.


#12

SpringFlowers AutumnMoon wrote:
[…]

then the code generated is

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

<%=h my_string%>

Best,

Marnen Laibow-Koser
http://www.marnen.org
removed_email_address@domain.invalid