Add a “hook” to all AJAX requests on a page

I’d like to know if it’s possible to “hook” into every single AJAX request (either as it’s about to get sent, or on events) and perform an action. At this point I’m assuming that there are other third-party scripts on the page. Some of these might use jQuery, while others do not. Is this possible?

Add a “hook” to all AJAX requests on a page

I’d like to know if it’s possible to hook into every single AJAX request (either as it’s about to get sent, or on events) and perform an action. At this point I’m assuming that there are other third

How to disable all AJAX requests in a page with jQuery and Javascript ?

I have a page and I would like to disable all AJAX requests with jQuery. Do you have any ideas? And if it is possible? if (false) { //disable all ajax requests }

Monitoring all AJAX requests made by JQuery?

Is there a way to monitor all ajax requests that have been made using JQuery on a page, and to have a callback function be called with the result of each request? E.g I make my ajax requests: $.get(‘f

Add custom http header to all jQuery AJAX Requests

Point of clarification: I don’t have any problem adding a custom header to my jQuery ajax call, I want to have my custom header added to all ajax calls automatically. If you take a look at jquery $.aj

Stop all active ajax requests in jQuery

I have a problem, when submitting a form all active ajax request fail, and that triggers error event. How to stop all active ajax requests in jQuery without trigerring error event?

jQuery remove all $.ajax requests from $.ajax loaded content

I am creating a page that a user can click a link and it will $.ajax load the content into a container div. The problem is the source files all have $.ajax requests of there own, so when a user clicks

jQuery abandon all outstanding AJAX requests

Is there any easy way to abandon all outstanding jQuery AJAX requests? My application is capable of pulling off a lot of simultaneous requests, so race becomes problematic. I’ve put in hackish solutio

Abort all JQuery AJAX requests globally

Is there a way to abort all AJAX requests globally without a handle on the request object? The reason I ask is that we have quite a complex application where we are running a number of different AJAX

Redirect all page requests to one page

I need to redirect all page requests (php, if that matters) on a specific domain to a specific page (again, php) on that domain. I’m looking for a .htaccess, mod_rewrite solution for easy of implement

Do AJAX requests effect page views? [closed]

Because webfont distributors base their licensing off of page views, would AJAX requests (.load()) have an effect? Example: $(‘#read’).load(‘index.php #read’); // update #read div $(‘#watch’).load(‘in

Answers

There is a trick to do it.

Before all scripts running, take the original XHMHttpReuqest object and save it in a different var. Then override the original XMLHttpRequest and direct all calls to it via your own object.

Psuedo code:

 var savd = XMLHttpRequest;
 XMLHttpRequest.prototype = function() {
         this.init = function() {
         }; // your code
         etc' etc'
 };

Since you mention jquery, I know jquery offers a .ajaxSetup() method that sets global ajax options that include the event triggers like success, error, and beforeSend – which is what sounds like what you are looking for.

$.ajaxSetup({
    beforeSend: function() {
        //do stuff before request fires
    }
});

of course you would need to verify jQuery availability on any page you attempt to use this solution on.

Inspired by aviv’s answer, I did a little investigating and this is what I came up with.
I’m not sure that it’s all that useful as per the comments in the script and of course will only work for browsers using a native XMLHttpRequest object.
I think it will work if javascript libraries are in use as they will use the native object if possible.

function addXMLRequestCallback(callback){
    var oldSend, i;
    if( XMLHttpRequest.callbacks ) {
        // we've already overridden send() so just add the callback
        XMLHttpRequest.callbacks.push( callback );
    } else {
        // create a callback queue
        XMLHttpRequest.callbacks = [callback];
        // store the native send()
        oldSend = XMLHttpRequest.prototype.send;
        // override the native send()
        XMLHttpRequest.prototype.send = function(){
            // process the callback queue
            // the xhr instance is passed into each callback but seems pretty useless
            // you can't tell what its destination is or call abort() without an error
            // so only really good for logging that a request has happened
            // I could be wrong, I hope so...
            // EDIT: I suppose you could override the onreadystatechange handler though
            for( i = 0; i < XMLHttpRequest.callbacks.length; i++ ) {
                XMLHttpRequest.callbacks[i]( this );
            }
            // call the native send()
            oldSend.apply(this, arguments);
        }
    }
}

// e.g.
addXMLRequestCallback( function( xhr ) {
    console.log( xhr.responseText ); // (an empty string)
});
addXMLRequestCallback( function( xhr ) {
    console.dir( xhr ); // have a look if there is anything useful here
});

I don’t have enough rep to add a comment to meouw’s answer, so I will comment as an answer (with apologies … 🙂

I had to inject code into an iframe which intercepts XHR calls, and used the above answer. However, I had to change

XMLHttpRequest.prototype.send = function(){

To:

XMLHttpRequest.prototype.send = function(arguments)

And I had to change

oldSend.apply(this, arguments);

To:

oldSend.call(this, arguments);

This was necesary to get it working in IE9 under IE8 document mode. If this modification was not made, some call-backs generated by the component framework (Visual WebGUI) did not work. More info at these links:

Function.prototype.call

Function.prototype.apply

Without these modifications AJAX postbacks did not terminate.

jquery…

<script>
   $(document).ajaxSuccess(
        function(event, xhr, settings){ 
          alert(xhr.responseText);
        }
   );
</script>

Using the answer of “meouw” I suggest to use the following solution if you want to see results of request

function addXMLRequestCallback(callback) {
    var oldSend, i;
    if( XMLHttpRequest.callbacks ) {
        // we've already overridden send() so just add the callback
        XMLHttpRequest.callbacks.push( callback );
    } else {
        // create a callback queue
        XMLHttpRequest.callbacks = [callback];
        // store the native send()
        oldSend = XMLHttpRequest.prototype.send;
        // override the native send()
        XMLHttpRequest.prototype.send = function() {
            // call the native send()
            oldSend.apply(this, arguments);

            this.onreadystatechange = function ( progress ) {
               for( i = 0; i < XMLHttpRequest.callbacks.length; i++ ) {
                    XMLHttpRequest.callbacks[i]( progress );
                }
            };       
        }
    }
}

addXMLRequestCallback( function( progress ) {
    if (typeof progress.srcElement.responseText != 'undefined' &&                        progress.srcElement.responseText != '') {
        console.log( progress.srcElement.responseText.length );
    }
});

If you don’t have to support <= IE8 you can do this which will generically intercept any AJAX globally and not screw up any callbacks etc. that maybe have been assigned by any third party AJAX libraries. The accepted answer does not yield the actual response because it is getting called too early.

(function() {
    var origOpen = XMLHttpRequest.prototype.open;
    XMLHttpRequest.prototype.open = function() {
        console.log('request started!');
        this.addEventListener('load', function() {
            console.log('request completed!');
            console.log(this.readyState); //will always be 4 (ajax is completed successfully)
            console.log(this.responseText); //whatever the response was
        });
        origOpen.apply(this, arguments);
    };
})();

Some more docs of what you can do here with the addEventListener API here:

https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/Using_XMLHttpRequest#Monitoring_progress

I’ve found a good library on Github that does the job well, you have to include it before any other js files

https://github.com/jpillora/xhook

here is an example that adds an http header to any incoming response

xhook.after(function(request, response) {
  response.headers['Foo'] = 'Bar';
});