开发者

How do I prevent javascript returned from an ajax request from executing when the response is inserted into the DOM?

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?


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

  • jQuery: Parse/Manipulate HTML without executing scripts
  • XSS Cheat Sheet


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.


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.


 $('body').html(response.replace(/(<script)[^\>]*/g,'$1 src="emptyfile.js"'));

where emptyfile.js exists but has no content.


The problem you have is that jQuery strips script tags from the html and creates a document fragment.

To elaborate

var e = $("<div>Hello</div><script>alert('hi')</script>")
e.html(); // will not display script tags as script tags are now in a document fragment
$("body").append(e); // will execute the script tags in the fragment

See John Resig's explanation and another forum post on this topic.

So, what you can do is

var e = $("<div>Hello</div><script>alert('hi')</script>")
e.filter("script").each(function(){this.text='';});

That would basically make all the scripts empty and now you can

$("body").append(e);

See this post for the fragment creating routine.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜