Yuliy Yuliy - 2 months ago 12
Ajax Question

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?

Answer

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
});
Comments