views:

95

answers:

6

I have some addHtml JavaScript function in my JS code. I wonder how to escape HTML/JS code properly. Basically, what I am trying right now is:

addHtml("<a onclick=\"alert(\\\"Hello from JS\\\")\">click me</a>")

However, that doesn't work. It adds the a element but it doesn't do anything when I click it.

I don't want to replace all " by ' as a workaround. (If I do, it works.)

+1  A: 
addHtml("<a onclick='alert(\"Hello from JS\")'>click me</a>")
jweber
That doesn't work if the JS code includes some `'`.
Albert
That's right it's not a general solution, it's just a solution to the string you provided. I think you have to escape the string before passing it to the function.
jweber
Yes, that was what my question is about. :) How do I escape the string.
Albert
A: 

What does the final HTML rendered in the browser look like ? I think the three slashes might be causing an issue .

jmhowwala
Yes it does not work, that is what the question is all about. :)
Albert
+1  A: 

My solution would be

addHtml('<a onclick="alert(\'Hello from JS\')">click me</a>') 

I typically use single quotes in Javascript strings, and double quotes in HTML attributes. I think it's a good rule to follow.

Fosco
I may want to use more complex JS code snippets there and I want to escape it in a general way that it always works. Just replacing all `"` by `'` would probably not work in all cases.
Albert
You would replace all ' with \'
Fosco
And how would I replace the `"` if there are any in the JS code? What if I want to put the full `addHtml(...)` again as the onclick code? (I need a general solution which works for just any code.)
Albert
The odds are pointing to the idea that you have made a poor design decision.
Fosco
I found, when trying to solve exactly this problem, that on an older version of FireFox that you had to be careful which way around you did the quotes: double inside single, or single inside double? The former didn't always work! Avoiding the need to handle this is better.
staticsan
+2  A: 

How about this?

addHtml("<a onclick=\"alert(&quot;Hello from JS&quot;)\">click me</a>");

It worked when I tested in Firefox, at any rate.

Tim Goodman
Ah thanks, so just replacing all `"` by `"` and it will always work? Well, at least all cases I have tested so far. And tested in Webkit.
Albert
I came up with this final solution now (which does exactly that): http://pastebin.com/QQig9y82
Albert
A: 

The problem is probably this...

As your code is now, it will add this to the HTML

<a onclick="alert("Hello from Javascript")"></a>

This is assuming the escape slashes will all be removed properly.

The problem is that the alert can't handle the " inside it... you'll have to change those quotes to single quotes.

addHtml("<a onclick=\"alert(\\\'Hello from JS\\\')\">click me</a>")

That should work for you.

Shaded
+5  A: 

I wonder how to escape HTML/JS code properly.

To insert string content into an HTML event handler attribute:

(1) Encode it as a JavaScript string literal:

alert("Hello \"world\"");

(2) Encode the complete JavaScript statement as HTML:

<a onclick="alert(&quot;Hello \&quot;world\&quot;&quot;">foo</a>

And since you seem to be including that HTML inside a JavaScript string literal again, you have to JS-encode it again:

html= "<a onclick=\"alert(&quot;Hello \\&quot;world\\&quot;&quot;\">foo<\/a>";

Notice the double-backslashes and also the <\/, which is necessary to avoid a </ sequence in a <script> block, which would otherwise be invalid and might break.

You can make this less bad for yourself by mixing single and double quotes to cut down on the amount of double-escaping going on, but you can't solve it for the general case; there are many other characters that will cause problems.

All this escaping horror is another good reason to avoid inline event handler attributes. Slinging strings full of HTML around sucks. Use DOM-style methods, assigning event handlers directly from JavaScript instead:

var a= document.createElement('a');
a.onclick= function() {
    alert('Hello from normal JS with no extra escaping!');
};
bobince
Great answer, bobince. I basically came up with my answer of `addHtml("<a onclick=\"alert("Hello from JS")\">click me</a>");` by trial and error, but this makes clear *why* it worked.
Tim Goodman
Thanks a lot, that makes it very clear.
Albert