Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
504 views
in Technique[技术] by (71.8m points)

javascript - Intercept XMLHttpRequest and modify responseText

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?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...