Monkey patch XMLHTTPRequest.onreadystatechange

Comment pourrait-on parler de la configuration de la fonction onreadystatechange du XMLHTTPRequest sur monkey. J'essaie d'ajouter une fonction qui sera appelée lorsque chaque demande d'ajax faite à partir d'une page revient.

Je sais que cela ressemble à une idée terrible, mais le cas d'utilisation est assez particulier. Je souhaite utiliser un certain SDK avec une console (jqconsole) mais afficher l'état et les résultats des appels ajax dans la console sans modifier le SDK externe.

J'ai regardé cette publication qui avait une excellente information, mais rien sur le repose de monkey sur le rappel qui semble dépasser mes compétences JavaScript.

PS Ne peut pas utiliser jQuery car il prend uniquement en charge les appels ajax effectués à partir de jQuery et non directement de XMLHTTPRequests ce qui est le cas ici.

Pour monter le patch XMLHttpRequest s, vous devez savoir comment une requête AJAX est généralement construite:

  1. Invocation du constructeur
  2. Préparation de la requête ( setRequestHeader() , open() )
  3. Envoi de la demande ( .send ).

Empreinte à usage général

 (function(xhr) { function banana(xhrInstance) { // Example console.log('Monkey RS: ' + xhrInstance.readyState); } // Capture request before any network activity occurs: var send = xhr.send; xhr.send = function(data) { var rsc = this.onreadystatechange; if (rsc) { // "onreadystatechange" exists. Monkey-patch it this.onreadystatechange = function() { banana(this); return rsc.apply(this, arguments); }; } return send.apply(this, arguments); }; })(XMLHttpRequest.prototype); 

Le précédent supposait que onreadystatechange était affecté au gestionnaire onreadystatechange . Pour simplifier, je n'ai pas inclus le code pour d' autres événements , comme onload . En outre, je n'ai pas tenu compte des événements ajoutés en utilisant addEventListener .

Le patch précédent s'exécute pour toutes les demandes. Mais que faire si vous souhaitez limiter le patch à une requête spécifique uniquement? Une demande avec un certain URL ou un drapeau asynchrone et un corps de demande spécifique?

Patch monétaire conditionnel

Exemple: intercepter toutes les requêtes POST dont le corps de demande contient "TEST"

 (function(xhr) { function banana(xhrInstance) { // Example console.log('Monkey RS: ' + xhrInstance.readyState); } // var open = xhr.open; xhr.open = function(method, url, async) { // Test if method is POST if (/^POST$/i.test(method)) { var send = this.send; this.send = function(data) { // Test if request body contains "TEST" if (typeof data === 'string' && data.indexOf('TEST') >= 0) { var rsc = this.onreadystatechange; if (rsc) { // Apply monkey-patch this.onreadystatechange = function() { banana(this); return rsc.apply(this, arguments); }; } } return send.apply(this, arguments); }; } return open.apply(this, arguments); }; })(XMLHttpRequest.prototype); 

Les principales techniques utilisées sont la réécriture transparente en utilisant …

 var original = xhr.method; xhr.method = function(){ /*...*/; return original.apply(this, arguments); }; 

Mes exemples sont très basiques et peuvent être étendus pour répondre à vos souhaits. Cela dépend de vous, cependant.

En supposant que vous pouvez ignorer IE …

 //Totally untested code, typed at the SO <textarea>... but the concept *should* work, let me know if it doesn't. var OldXMLRequest = XMLHttpRequest; // Create a new instance function XMLHttpRequest() { var ajax = new OldXMLRequest(); // save old function var f = ajax.onreadystatechange; ajax.onreadystatechange = function() { console.log("Whatever!"); f(); // Call the old function } return ajax; } 

Vous pouvez apprendre de Ajax-hook écrit par le chinois!

Il s'agit d'un js avancé pour activer le patch macros XMLHTTPRequest