web-dev-qa-db-fra.com

JavaScript: Détecte AJAX requêtes

Existe-t-il un moyen de détecter les appels globaux AJAX (en particulier les réponses) sur une page Web avec JavaScript générique (pas avec les frameworks)?

J'ai déjà examiné la question " JavaScript détecte un AJAX ", ici sur StackOverflow, et j'ai essayé de corriger le code de réponse accepté dans mon application, mais cela n'a pas été le cas ' Je n'ai jamais rien fait avec AJAX avant non plus donc je ne sais pas assez pour le modifier pour qu'il fonctionne.

Je n'ai besoin de rien d'extraordinaire, j'ai juste besoin de tout détecter (spécifique, en fait, mais je devrais tout d'abord détecter et partir de là) AJAX réponses et les patcher dans un IF Donc, finalement, j'aimerais quelque chose comme:

if (ajax.response == "certainResponseType"){
    //Code
}

, par exemple.

Mise à jour: Il semble que je devrais préciser que je n'essaie pas d'envoyer une demande - je développe un script de contenu et je dois pouvoir détecter les demandes de la page Web AJAX (pas les miennes), afin que je puisse exécuter une fonction lorsqu'une réponse est détectée.

31
mythofechelon

Voici du code (testé en collant dans la console Chrome 31.0.1650.63) pour intercepter et consigner ou autrement traiter les demandes ajax et leurs réponses:

(function() {
    var proxied = window.XMLHttpRequest.prototype.send;
    window.XMLHttpRequest.prototype.send = function() {
        console.log( arguments );
        //Here is where you can add any code to process the request. 
        //If you want to pass the Ajax request object, pass the 'pointer' below
        var pointer = this
        var intervalId = window.setInterval(function(){
                if(pointer.readyState != 4){
                        return;
                }
                console.log( pointer.responseText );
                //Here is where you can add any code to process the response.
                //If you want to pass the Ajax request object, pass the 'pointer' below
                clearInterval(intervalId);

        }, 1);//I found a delay of 1 to be sufficient, modify it as you need.
        return proxied.apply(this, [].slice.call(arguments));
    };


})();

Ce code résout le problème ci-dessus avec la réponse acceptée:

Notez que cela peut ne pas fonctionner si vous utilisez des frameworks (comme jQuery), car ils peuvent remplacer onreadystatechange après avoir appelé send (je pense que jQuery le fait). Ou ils peuvent remplacer la méthode d'envoi (mais cela est peu probable). C'est donc une solution partielle.

Parce qu'il ne repose pas sur le rappel "onreadystatechange" qui n'est pas modifié, mais surveille le "readyState" lui-même.

J'ai adapté la réponse d'ici: https://stackoverflow.com/a/7778218/1153227

31
Omn

Cela peut être un peu délicat. Que dis-tu de ça?

var _send = XMLHttpRequest.prototype.send;
XMLHttpRequest.prototype.send = function() {

    /* Wrap onreadystaechange callback */
    var callback = this.onreadystatechange;
    this.onreadystatechange = function() {             
         if (this.readyState == 4) {
             /* We are in response; do something,
                like logging or anything you want */
         }
         callback.apply(this, arguments);
    }

    _send.apply(this, arguments);
}

Je ne l'ai pas testé, mais ça a l'air plus ou moins bien.

Notez que cela peut ne pas fonctionner si vous utilisez des frameworks (comme jQuery), car ils peuvent remplacer onreadystatechange après avoir appelé send (je pense que jQuery le fait). Ou ils peuvent remplacer la méthode send (mais cela est peu probable). C'est donc une solution partielle.

EDIT: De nos jours (début 2018) cela devient plus compliqué avec la nouvelle API fetch . La fonction globale fetch doit également être remplacée de manière similaire.

21
freakish

Essaye cela. Détecte les réponses Ajax, puis j'ai ajouté un conditionnel en utilisant les propriétés XMLHttpRequest readyState & status pour exécuter la fonction si le statut de la réponse = OK

var oldXHR = window.XMLHttpRequest;

function newXHR() {
    var realXHR = new oldXHR();
    realXHR.addEventListener("readystatechange", function() {
        if(realXHR.readyState==4 && realXHR.status==200){
            afterAjaxComplete() //run your code here
        }
    }, false);
    return realXHR;
}
window.XMLHttpRequest = newXHR;

Modifié à partir de: Surveillez tous les événements JavaScript dans la console du navigateur

20
mmguy