我正在尝试构建一个脚本,它将充当本地XMLHttpRequest
对象的代理/包装器,使我能够拦截它,修改responseText并返回原始的onreadystatechange事件。
如果应用程序尝试接收的数据已在本地存储中可用,则上下文将中止XMLHttpRequest
并将本地存储的数据传递回应用程序成功/失败回调方法。假设我无法控制应用程序现有的AJAX回调方法。
我最初尝试过以下想法..
var send = XMLHttpRequest.prototype.send;
XMLHttpRequest.prototype.send = function(data){
//Do some stuff in here to modify the responseText
send.call(this, data);
};
但正如我现在所建立的那样,responseText是只读的。
然后我尝试退后一步,将自己的完整本机代理编写到XMLHttpRequest
,最终编写了我自己的本机方法版本。与此处讨论的相似......
http://www.ilinsky.com/articles/XMLHttpRequest/#implementation-wrapping
但它很快就让人感到困惑,并且仍然难以将修改后的数据恢复回原来的onReadyStateChange
方法。
有什么建议吗?这甚至可能吗?
答案 0 :(得分:4)
//
// 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();
}
答案 1 :(得分:0)
你的退步是一种过度杀伤:你可以在XMLHttpRequest上添加你自己的getter:(more about properties)
Object.defineProperty(XMLHttpRequest.prototype,"myResponse",{
get: function() {
return this.responseText+"my update"; // anything you want
}
});
用法:
var xhr = new XMLHttpRequest();
...
console.log(xhr.myResponse); // xhr.responseText+"my update"
在现代浏览器上 注意,您可以运行xhr.onload
(参见XMLHttpRequest2 tips)
答案 2 :(得分:0)
以下脚本在通过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>