can i remove the X-Requested-With header from ajax requests?

mkoryak picture mkoryak · Jul 30, 2010 · Viewed 26.7k times · Source

I wanted to know if anyone has had experience with trying to remove the 'X-Requested-With' header from the ajax request made by jquery (or plain JS). is it possible?

2nd part: do you know if Grease Monkey's ajax requests set this header?

Thanks

header looks like this:

X-Requested-With XMLHttpRequest

Answer

Synexis picture Synexis · Jul 13, 2014

The solution for removing the header in jQuery proposed by @vamp is on the right track, but as others have stated it will still result in an empty X-Requested-With header being sent.

The beforeSend callback receives jQuery's XHR object (jqXHR), rather than the actual XMLHttpRequest object (xhr), which is not even instantiated until after beforeSend is called.

The setRequestHeader method in jqXHR adds headers to an object, which is then iterated later using the xhr method of the same name, just after adding the X-Requested-With entry to the headers object.

Here's the part in jQuery where this is happening:

if ( !options.crossDomain && !headers["X-Requested-With"] ) {
    headers["X-Requested-With"] = "XMLHttpRequest";
}

for ( i in headers ) {
    xhr.setRequestHeader( i, headers[ i ] );
}

Which leads to the problem: If you don't specify the X-Requested-With header, then jQuery will (unless the crossDomain setting evaluates false, but that may not be the desired solution). It then immediately sets the xhr headers, which can not be unset.


To prevent sending the X-Requested-With header with jQuery.ajax:

jQuery.ajax provides a setting, xhr, which overrides jQuery's built-in factory method for creating the XMLHttpRequest object. By wrapping this factory method, and then wrapping the browser's native setRequestHeader method, the call from jQuery to set the X-Requested-With header can be ignored.

jQuery.ajax({

    url: yourAjaxUrl,

    // 'xhr' option overrides jQuery's default
    // factory for the XMLHttpRequest object.
    // Use either in global settings or individual call as shown here.
    xhr: function() {
        // Get new xhr object using default factory
        var xhr = jQuery.ajaxSettings.xhr();
        // Copy the browser's native setRequestHeader method
        var setRequestHeader = xhr.setRequestHeader;
        // Replace with a wrapper
        xhr.setRequestHeader = function(name, value) {
            // Ignore the X-Requested-With header
            if (name == 'X-Requested-With') return;
            // Otherwise call the native setRequestHeader method
            // Note: setRequestHeader requires its 'this' to be the xhr object,
            // which is what 'this' is here when executed.
            setRequestHeader.call(this, name, value);
        }
        // pass it on to jQuery
        return xhr;
    },

    success: function(data, textStatus, jqXHR) {
        // response from request without X-Requested-With header!
    }

    // etc...

});