Tell me more ×
Stack Overflow is a question and answer site for professional and enthusiast programmers. It's 100% free, no registration required.

I'm looking at this Railscast episode and wondering why the call to escape_javascript is needed here:

$("#reviews").append("<%= escape_javascript(render(:partial => @review)) %>");

What is escape_javascript used for?

According to the Rails docs:

escape_javascript(javascript)

Escape carrier returns and single and double quotes for JavaScript segments.

But that doesn't mean much to me.

share|improve this question

4 Answers

up vote 9 down vote accepted

Because you don't want users posting JavaScript that the browser actually executes?

share|improve this answer
But how about when you want to pass and render javascript code? – berto77 Feb 22 '12 at 3:38

It's easier to understand if you split the code in two parts.

The first part $("#reviews").append("...") is rjs. This means that it is ruby code that will get transformed to javascript code and then sent to the client. This piece concretely will use javascript to add something to any dom node with an id of "reviews" - but that is not important for your question. What is important is that you will be generating javascript.

Another important thing to take into account is that in this particular case, the javascript uses a string, generated by ruby - the "...". It is one string with double quotes(""). Hold on to that knowledge piece for a moment.

Now think of what render(:partial => @review) is doing.

It is rendering a partial - which means that it could be rendering any kind of code - html, css ... or even more javascript!

So, what happens if our partial renders something like this?

<a href="/mycontroller/myaction">Action!</a> 

Remember that your javascript was taking a double-quoted string as a parameter? Now see what you are generating - inmediately after the href= there is a double quote character! That will close your string before it should!

$("#reviews").append("<a href="/mycontroller/myaction">Action!</a> ") #gives you an error

In order for this not to happen, you want to escape these special characters so your string is not cut - like this:

<a href=\"/mycontroller/myaction\">Action!</a>

This is done by using escape_javascript.

$("#reviews").append("<a href=\"/mycontroller/myaction\">Action!</a>")

Regards!

share|improve this answer
3  
Great explanation, this example should be on the documentation :) – Hallucynogenyc Aug 22 '12 at 10:30

users may post malicious code (malicious users) that if left unescaped will potentially get executed, allowing users to control your application.

try this:

<% variable = '"); alert("hi there' %>
$("#reviews").append("<%= variable %>");

not really familiar with the syntax of rails, but if you don't escape variable then an alert box will show, and i dont think that is intended behaviour.

share|improve this answer

If you look at the source here, it will be much clearer.

This function accomplishes the following two things:

  1. It substitutes the characters in the input string with the ones defined in JS_ESCAPE_MAP

    The purpose of this is to make sure that the javascript code is serialized correctly without interfering with the outer string within which it is being embedded. For example if you have a javascript string in double quotes then all the quotes within for string literals must be in single quotes to avoid the code from breaking.

  2. The function also checks if the resulting string is html safe. If it is not then it does the necessary escaping to make sure that the string becomes html safe and returns the result.

When you are using escape_javascript, it is usually being embedded within another string or existing html dynamically. You need to make sure that doing this will not make your entire page not render.

Some aspects of this response were pointed out in other responses but I wanted to bring all the items together include the difference between javascript escaping and html escaping. Also, some responses allude that this function helps to avoid script injection. I don't think that is the purpose of this function. For example, in your review if your review has alert('hi there'), just appending it to the node will not fire the pop-up. You are not embedding it within a function that is triggered on page load or through some other event. Merely having alert('hi there') as part of your html does not mean that it will execute as javascript.

That said I am not denying that script injection is not possible. But to avoid that you need to take steps when you take the user data and store it in your database. The function and example you are providing are related to rendering the information, which was already saved.

I hope this helps and answers your question.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.