Rectangle 27 0

prevent jquery ajax to execute javascript from script or html response?


$.ajax('myscript.js', {
    dataType: 'text',
    success: function (response) {
        // Do something with the response
    }
})

If text or html is specified, no pre-processing occurs. The data is simply passed on to the success handler, and made available through the responseText property of the jqXHR object.

Lee's answer already adequately addresses the case of HTML responses - scripts embedded in these are not in fact executed automatically unless you add the HTML to the DOM, contrary to the erroneous documentation you quoted.

Setting dataType to 'text' will cause jQuery to disregard the Content-Type header returned from the server and treat the response like plain text, thus preventing the default behaviour for JavaScript responses (which is to execute them). From the (recently corrected) docs:

That leaves the other case asked about in your question title - preventing script responses from being executed automatically when received. You can do this easily using the dataType setting.

The type of pre-processing depends by default upon the Content-Type of the response, but can be set explicitly using the dataType option. If the dataType option is provided, the Content-Type header of the response will be disregarded.

Note
Rectangle 27 0

prevent jquery ajax to execute javascript from script or html response?


edit_dialog.html($($.parseHTML(response)));
edit_dialog.html(response);
html
jqXHR
text

no pre-processing occurs. The data is simply passed on to the success handler

"html": Returns HTML as plain text; included script tags are evaluated when inserted in the DOM.

If you don't want to evaluate the scripts before inserting your response in to the DOM, you should be able to do something like:

It depends on the dataType of the ajax request. The OP is clearly returning HTML, in which case scripts are not executed until insertion. From the jquery docs: '"html": Returns HTML as plain text; included script tags are evaluated when inserted in the DOM.' if you make an ajax request to a .js file, I presume jQuery guesses "script" as the dataType and as per the docs, evaluates the scripts immediately: '"script": Evaluates the response as JavaScript and returns it as plain text.'

The scripts are evaluated in this case when you call

Your claim that Jquery .ajax does not evaluate scripts on return is simply false. The documentation at api.jquery.com/jQuery.ajax explicitly contradicts your claim, and the OP even quoted the relevant section for you. Yes, it's surpising behaviour (at least, I was surprised when I discovered this), but it's trivial to test and confirm that it's true. Just create a .js file that contains console.log('hello world'); and a HTML page which includes jQuery and an inline script that does $.ajax('yourscript.js');. You'll see 'hello world' in the console.

jQuery.ajax does not evaluate scripts on return when requesting HTML. The passage you quoted in the question was in fact a long-standing error in the documentation, fixed as of April 2014. The new docs have this to say (emphasis mine):

parseHTML is the key in that by default it removes script tags. However, be aware that parseHTML is NOT XXS safe and if your source is unknown this is still a security concern.

you are quite right; forgive my misguided downvote. I've made a small edit to your answer to include the quote you just posted, and have reverted my downvote. I remain somewhat confused since the documentation the OP quoted and the documentation that you have quoted appear to directly contradict each other. Testing reveals that the section you quoted is the one which is correct, but I don't understand why the bit that the OP quoted (If html is specified, any embedded JavaScript inside the retrieved data is executed before the HTML is returned as a string.) is in the docs at all.

Note
Rectangle 27 0

prevent jquery ajax to execute javascript from script or html response?


$.ajax({
  url: "example.html",
  type: "GET",
  dataType: "html",
  succes: function(data){
     // Example: alert(data);
     // Do whatever you want with the returned data using JS or jQuery methods
  }
});

I agree that js is not proper datatype. Just a typo in the post here. I meant dataType:'script' and I can't change the dataType as I don't know what response I will receive.

I don't suggest you use a function like that, as you might lose a lot of data or cause for unwanted behaviour. Instead of calling external javascript methods through ajax, just include them in your code and you can call them whenever you want. Without a work around function like youre describing.

The documentation states that any embedded Javascript inside the retrieved data will be executed before the HTML is returned as a string. If you want to then alter whatever you have retrieved using your ajax call, you can do so within the succes property:

When I receive only js (dataType:'js'), and in the success function I do eval of the response, it is executed twice. First by my eval, then by the jquery itself as described in the documentation. similar is with html.

Why would you need to use an ajax call to receive only JS? Also, js is not an allowed datatype. Allowed datatypes are: xml, html, json, jsonp, script or text.

i have one function do_ajax(url) that perform ajax calls. It checks what it receives. when it is a js then it is executed, if html it create jqueryui dialog and put the content in the dialog.

Note
Rectangle 27 0

prevent jquery ajax to execute javascript from script or html response?


$.ajax('uri',{
    dataFilter: function(data, type)
    {
        type = type || 'text';
        if(type=='html'||type=='text'){
            /*return data.replace(/<script.*>.*?<\/script>/gi, '');*/
            return data.replace(/<script.*?>([\w\W\d\D\s\S\0\n\f\r\t\v\b\B]*?)<\/script>/gi, '');
        }
        return data;
    }
    , success: function(data)
    {
        // whatever
    }
});

Also, with respect to security - note that removing script tags isn't enough to render HTML from an untrusted source safe to insert into the DOM, since it may contain inline event handlers (e.g. <div onmouseover="alert('haxored u!!1')">)

It seems to me that this isn't the right solution in any circumstances. When requesting a JavaScript file, using dataType: 'text' is sufficient to prevent its execution. When requesting HTML, scripts in the result won't be executed unless/until you insert the HTML into the DOM, so if you want to automatically scrub out scripts, the best way would be by doing $response = $(response); $response.find('script').remove(); and then use the scrubbed $response instead of the raw HTML from then on. If you do it your way, Zalgo will get you.

NOTE if dataType hasnt been set in options it will be undefined in dataFilter so I just default it to text for the filter - if you remove that line then it will only work if dataType is explicitly set.

That's one of the really annoying things about jQuery that it executes javascript on response. Other frameworks like MooTools disable script execution from responses unless you specifically set that you want them executed which is a much better approach.

The only way I could figure to prevent scripts being executed is to add a custom dataFilter Its easy enough but I think it should be default and an ajax option to enable script execution if you want it (I've never had a use for it and other frameworks disable by default for security etc.)

Note