Monkey Patch XMLHTTPRequest.onreadystatechange

How would the monkey progress by correcting the XMLHTTPRequest onreadystatechange function. I am trying to add a function that will be called when every ajax request made from the page is returned.

I know this sounds like a terrible idea, but the use case is rather strange. I want to use a specific SDK with the console (jqconsole), but show the status and results from ajax calls inside the console without changing the external SDK.

I looked through this post , which had excellent information, but nothing happened when the monkey fixed the callback, which seems to be superior to my JavaScript skills.

PS It is impossible to use jQuery, since it only supports direct ajax calls made from jQuery, and not from XMLHTTPRequests , which is the case here.

+7
javascript ajax monkeypatching
Sep 25
source share
3 answers

In order to monkey-patch XMLHttpRequest s, you need to know how the AJAX request is usually created:

  • Constructor Call
  • Request preparation ( setRequestHeader() , open() )
  • Sending a request ( .send ).

General purpose patch

 (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); 

It was previously assumed that onreadystatechange was assigned to the onreadystatechange handler. For simplicity, I did not include other events , such as onload . In addition, I did not account for events added with addEventListener .

The previous patch runs for all requests. But what if you want to restrict the patch to just a specific request? A request with a specific URL or asynchronous flag and a specific request object?

Conditional Monkey Patch

Example: Intercepting all POST requests whose request body contains "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); 

The main methods used are transparent recycling using ...

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

My examples are very simple and can be extended to suit your exact wishes. This is for you, however.

+9
Sep 25
source

You can learn from Ajax-hook written by Chinese!

this is advanced js to enable Monkey patch XMLHTTPRequest

+1
Jun 03 '17 at 2:39 on
source

Assuming you can ignore 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; } 
0
Sep 25
source



All Articles