I'm trying to build a script that will act as a proxy/wrapper for the native XMLHttpRequest
object enabling me to intercept it, modify the responseText and return back to the original onreadystatechange event.
The context being, if the data the app is trying to receive is already available in local storage, to abort the XMLHttpRequest
and pass the locally stored data back into the apps success/failure callback methods. Assume I have no control over the apps existing AJAX callback methods.
I had originally tried the following idea..
var send = XMLHttpRequest.prototype.send;
XMLHttpRequest.prototype.send = function(data){
//Do some stuff in here to modify the responseText
send.call(this, data);
};
But as I have now established, the responseText is read only.
I then tried taking a step back, writing my own full native proxy to XMLHttpRequest
, ultimately ending up writing my own version of the native methods. Similar to what is discussed here...
http://www.ilinsky.com/articles/XMLHttpRequest/#implementation-wrapping
But it rapidly got confusing, and still have the difficulty of returning the modified data back into the original onReadyStateChange
method.
Any suggestions? Is this even possible?
//
// firefox, ie8+
//
var accessor = Object.getOwnPropertyDescriptor(XMLHttpRequest.prototype, 'responseText');
Object.defineProperty(XMLHttpRequest.prototype, 'responseText', {
get: function() {
console.log('get responseText');
return accessor.get.call(this);
},
set: function(str) {
console.log('set responseText: %s', str);
//return accessor.set.call(this, str);
},
configurable: true
});
//
// chrome, safari (accessor == null)
//
var rawOpen = XMLHttpRequest.prototype.open;
XMLHttpRequest.prototype.open = function() {
if (!this._hooked) {
this._hooked = true;
setupHook(this);
}
rawOpen.apply(this, arguments);
}
function setupHook(xhr) {
function getter() {
console.log('get responseText');
delete xhr.responseText;
var ret = xhr.responseText;
setup();
return ret;
}
function setter(str) {
console.log('set responseText: %s', str);
}
function setup() {
Object.defineProperty(xhr, 'responseText', {
get: getter,
set: setter,
configurable: true
});
}
setup();
}
The following script perfectly intercept the data before sending via XMLHttpRequest.prototype.send
<script>
(function(send) {
XMLHttpRequest.prototype.send = function(data) {
this.addEventListener('readystatechange', function() {
}, false);
console.log(data);
alert(data);
};
})(XMLHttpRequest.prototype.send);
</script>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With