Forum: Ruby on Rails How to pass data to Javascript variable from Ruby on Rails

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
winter h. (Guest)
on 2009-04-08 09:31
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.
Chris K. (Guest)
on 2009-04-08 10:48
(Received via mailing list)
The most straightforward way of doing what you want is: <%= my_var %>

On Wed, Apr 8, 2009 at 7:31 AM, SpringFlowers AutumnMoon <
winter h. (Guest)
on 2009-04-08 13:48
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 %>
Robert W. (Guest)
on 2009-04-08 21:00
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.
Frederick C. (Guest)
on 2009-04-08 21:34
(Received via mailing list)
On Apr 8, 6:00 pm, Robert W. <removed_email_address@domain.invalid>
wrote:
> 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
winter h. (Guest)
on 2009-04-08 23:34
Frederick C. wrote:
> On Apr 8, 6:00�pm, Robert W. <removed_email_address@domain.invalid>
> wrote:
>> 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

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))   ?
winter h. (Guest)
on 2009-04-08 23:36
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.
winter h. (Guest)
on 2009-04-13 17:57
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.
Marnen L. (Guest)
on 2009-04-14 02:42
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
winter h. (Guest)
on 2009-04-14 13:08
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

<script type="text/javascript">

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

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

</script>


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>

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.
winter h. (Guest)
on 2009-04-14 13:58
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.
Marnen L. (Guest)
on 2009-04-14 21:34
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,
--
Marnen Laibow-Koser
http://www.marnen.org
removed_email_address@domain.invalid
This topic is locked and can not be replied to.