DEV Community

artydev
artydev

Posted on

AJAX Request Interceptor

Somtimes you need to trace Ajax call for debugging purpose.
Steve Fenton expose a nice trick to do so :
AJAX Request Interceptor

(function () {
    const arl = new Object();
    arl._open = XMLHttpRequest.prototype.open;
    arl._send = XMLHttpRequest.prototype.send;
    arl.callback = function () {
        const event = new CustomEvent('AjaxDetected', {
            detail: {
                url: this.url,
                method: this.method,
                data: this.data
            }
        });
        document.body.dispatchEvent(event);
    }

    function notNullString(input) {
        return input || '';
    }

    XMLHttpRequest.prototype.open = function (a, b) {
        a = notNullString(a);
        b = notNullString(b);

        arl._open.apply(this, arguments);
        arl.method = a;
        arl.url = b;

        if (a.toLowerCase() == 'get') {
            arl.data = b.split('?');
            arl.data = notNullString(arl.data[1]);
        }
    }

    XMLHttpRequest.prototype.send = function (a, b) {
        a = notNullString(a);
        b = notNullString(b);

        arl._send.apply(this, arguments);

        if (arl.method.toLowerCase() == 'post') {
            arl.data = a;
        }

        arl.callback();
    }
}());
Enter fullscreen mode Exit fullscreen mode

Here is another version :

(function () {
    /**
     * Objet pour logger les requêtes AJAX
     */
    const AjaxRequestLogger = {
        /**
         * Références aux méthodes originales de XMLHttpRequest
         */
        _methodeOriginaleOpen: XMLHttpRequest.prototype.open,
        _methodeOriginaleSend: XMLHttpRequest.prototype.send,

        /**
         * Fonction de callback pour déclencher l'événement personnalisé
         */
        callback: function () {
            const evenement = new CustomEvent('AjaxDetected', {
                detail: {
                    url: this.url,
                    methode: this.methode,
                    donnees: this.donnees
                }
            });
            document.body.dispatchEvent(evenement);
        },

        /**
         * Fonction utilitaire pour retourner une chaîne vide si l'entrée est null ou undefined
         */
        chaineNonNulle: function (entree) {
            return entree || '';
        },

        /**
         * Surcharge de la méthode open de XMLHttpRequest
         */
        surchargerMethodeOpen: function () {
            XMLHttpRequest.prototype.open = function (methode, url) {
                methode = AjaxRequestLogger.chaineNonNulle(methode);
                url = AjaxRequestLogger.chaineNonNulle(url);

                AjaxRequestLogger._methodeOriginaleOpen.apply(this, arguments);
                AjaxRequestLogger.methode = methode;
                AjaxRequestLogger.url = url;

                if (methode.toLowerCase() === 'get') {
                    AjaxRequestLogger.donnees = url.split('?')[1] || '';
                }
            };
        },

        /**
         * Surcharge de la méthode send de XMLHttpRequest
         */
        surchargerMethodeSend: function () {
            XMLHttpRequest.prototype.send = function (donnees) {
                donnees = AjaxRequestLogger.chaineNonNulle(donnees);

                AjaxRequestLogger._methodeOriginaleSend.apply(this, arguments);

                if (AjaxRequestLogger.methode.toLowerCase() === 'post') {
                    AjaxRequestLogger.donnees = donnees;
                }

                AjaxRequestLogger.callback();
            };
        },

        /**
         * Méthode d'initialisation
         */
        initialiser: function () {
            this.surchargerMethodeOpen();
            this.surchargerMethodeSend();
        }
    };

    AjaxRequestLogger.initialiser();
}());

Enter fullscreen mode Exit fullscreen mode

Usage :

document.body.addEventListener('AjaxDetected', function (e) {
    console.log(e.detail.method, e.detail.url, e.detail.data);
}, false);
Enter fullscreen mode Exit fullscreen mode

Heroku

Build apps, not infrastructure.

Dealing with servers, hardware, and infrastructure can take up your valuable time. Discover the benefits of Heroku, the PaaS of choice for developers since 2007.

Visit Site

Top comments (2)

Collapse
 
efpage profile image
Eckehard

Last time I needed an Ajax call is so long ago that I hardly remember how to use Ajax at all. The whole concept feels a bit like making fire with two woodsticks...

Image description

Is there any way to add this feature to the fetch-API ?

Collapse
 
artydev profile image
artydev

Hy Eckehard :-)

Look at this Interceptor

nextjs tutorial video

Youtube Tutorial Series 📺

So you built a Next.js app, but you need a clear view of the entire operation flow to be able to identify performance bottlenecks before you launch. But how do you get started? Get the essentials on tracing for Next.js from @nikolovlazar in this video series 👀

Watch the Youtube series