views:

55

answers:

4

So, I see so many people wondering how to execute JS code returned via ajax. I wish I had that problem. My JS executes, but I don't want it too!

Using jQuery 1.4.2, I'm making a GET request:

$.ajax({
  url:'/myurl/',
  type:'GET',
  success:function(response){
    $('body').html(response);
  }
});

The response looks something like:

<p>Some content</p> 
<script>alert("hi!");</script>

Whenever the success callback fires and the response is injected into the DOM, the alert code fires! I don't want that to happen. What can I do to prevent this?

A: 

If you can't modify the response, try to "replace" <script> tags:

"<script>alert('hi');</script>".replace(/<(\/?script)/gi, "&lt;$1");

This should escape the tags, making they appear as plain text instead of executing.

Related links

BrunoLM
I'm trying to avoid a regex solution. I have no idea who will be creating the response content, and if it's something crazy, I'd like to make sure the solution is infallible. Thanks for the suggestion though!
Kappers
@Kappers: That sounds complicated. I guess you would need some `xml parser`. I'm not sure if there is any in js. I guess you would need a second request to some service that remove potentially dangerous tags/attributes.
BrunoLM
I was under the impression that jQuery did something to remove scripts from collections when you inserted via .html(); I found an article from 2009 about it, and a buddy of mine actually had a problem recently where he wasn't seeing scripts in his response. I briefly looked at jQuery source and couldn't find any evidence of the strippage though. Not sure what I'm going to do just yet :)
Kappers
A: 

Depends. Do you need the JavaScript, or can you just get rid of it? If you don't need it at all, you could do something like

response = response.replace(/<script.*?<\/script>/gi, "");

However, if you need it, you're going to need to figure out how to kill just the function call(s) that you don't want. Using your example of an alert:

response = response.replace(/alert\(.*?\)/gi, "alert");

By getting rid of the trailing parens, and whatever they contain, you stop the function call from happening. Obviously, what you'll need in your regex will depend on the actual code that's causing the problem.

Sid_M
Yeah, the javascript can't go away. Unfortunately, I have no way of knowing *exactly* what will be produced in the response. It could be anything. The requirements state that it *could* contain scripts and that the full response needs to be injected on the page - including any script tags. As I mentioned to @BrunoLM, I'm leery of using regex for this simply because I don't know what the output will be. :(
Kappers
Without getting very complicated, I only see 3 options: (1) Don't mess with the JS, and make it clear that it's the responsibility of whoever introduces it on the server side; (2) Remove the JS completely as in my first regex; (3) Choose some very specific calls to kill, as in my second regex, and leave the rest alone. Anything else risks breaking something they want.
Sid_M
A: 
 $('body').html(response.replace(/(<script)[^\>]*/g,'$1 src="emptyfile.js"'));

where emptyfile.js exists but has no content.

kennebec
A: 

Hello there, did you try returning function() snippets like
<script>
function Hello(){
alert('Hello');
}
</script>

This way the your JS doesn't execute right away but can be called later when required. But, again it depends what you actually want to do.

Ajaxe