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.
Rob W Sep 25 2018-12-12T00: 00Z
source share