Blink Solution
Blink is Chrome, Opera etc.
In the XMLHttpRequest prototype, onreadystatechange declared as a getter / setter, and by specifying your getter / setter you need not to break the XMLHttpRequest operation logic:
var oldXMLHttpRequest = XMLHttpRequest; XMLHttpRequest = function() { var xhr = new oldXMLHttpRequest(); // получаем дескриптор прототипных setter/getter var descrGetSet = Object.getOwnPropertyDescriptor( Object.getPrototypeOf( xhr ), "onreadystatechange" ); var newSet = function( val ) { console.log ( "setter" ); descrGetSet.set.call( xhr, function() { // прототипный setter console.log( "Inject "+this.status ); // this.responseText return val.apply( xhr, arguments ); } ); } Object.defineProperty( xhr, "onreadystatechange", { set: newSet, // новый setter get: descrGetSet.get // старый getter } ); return xhr; }
Now do:
x = new XMLHttpRequest(); x.open( "GET", "/" ); x.send( null ) x.onreadystatechange = function () { console.log( this.statusText+' is 2' )};
Will see
Inject 200 OK is 2 Inject 200 OK is 2 Inject 200 OK is 2
What should be when changing the readyState .
Webkit Solution
Webkit - Safari, PhantomJS
The problem in this engine — onreadystatechange is the getter / setter of the XHR object, not XHR.prototype . As a result, you cannot override it. Inheriting from XHR also impossible, so you need to use a wrapper for XHR .
This wrapper is quite good:
https://github.com/ilinsky/xmlhttprequest