Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

prevent jquery ajax to execute javascript from script or html response

According to documentation:

If html is specified, any embedded JavaScript inside the retrieved data is executed before the HTML is returned as a string. Similarly, script will execute the JavaScript that is pulled back from the server, then return nothing.

How to prevent this? I have js that shall modify the content that is obtained through ajax. Executing it before the html is returned makes no sense as it does not have content to work on (at least in my case).

my code:

function do_ajax(url)
    {
    $.ajax(
        {
        cache: false,
        url : url,
        success: function(response, status, xhr)
            {
            var ct = xhr.getResponseHeader("content-type") || "";
            if (ct.indexOf('script') > -1) {
                try {
                eval(response);
                }
                catch(error) { }
                }
                else
                {
                var edit_dialog = $('<div class="edit_dialog" style="display:hidden"></div>').appendTo('body');
                edit_dialog.html(response);
                edit_dialog.dialog({ modal:true, close: function(event, ui) { $(this).dialog('destroy').remove(); } });
                }

            },
        error:function (xhr, ajaxOptions, thrownError){
                   alert(xhr.status);
                   alert(thrownError);
                }
        });
    }

the script received by ajax is executed twice. First by me in the eval(response), then jquery execute it again (as described in the documentation)

like image 482
Krzysztof Dk Avatar asked Nov 01 '11 10:11

Krzysztof Dk


People also ask

How do I stop multiple AJAX calls from repeated clicks?

}); If isLoading is false, the AJAX call starts, and we immediately change its value to true. Once the AJAX response is received, we turn the value of that variable back to false, so that we can stop ignoring new clicks.

How stop AJAX submit?

You'll need to stop it BEFORE the success handler. Because the function finishes executing after your AJAX call the form will submit while your ajax call is occurring (and by the time your ajax call finishes it is too late). But yes, put return false at the end of your function.

Can AJAX work without JavaScript?

AJAX isn't possible without Javascript, because it presupposes JS code running on the client. If JS is disabled, there's nothing that can execute in the browser and contact the server - only "dead" HTML and CSS. Flash is an alternative, but then again it can be disabled too.


2 Answers

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.

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.

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

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:

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.

...

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.

like image 143
Mark Amery Avatar answered Nov 03 '22 00:11

Mark Amery


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):

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

...

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.

The scripts are evaluated in this case when you call

edit_dialog.html(response);

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:

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

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.

like image 28
Lee Avatar answered Nov 02 '22 23:11

Lee