Tre*_*vor 16 javascript ajax overriding xmlhttprequest
我怎样才能覆盖该XMLHttpRequest.open()方法然后捕获并更改它的参数?
我已经尝试过代理方法,但它没有用,虽然XMLHttpRequest()在调用时删除了open over-rid :
(function() {
var proxied = window.XMLHttpRequest.open;
window.XMLHttpRequest.open = function() {
$('.log').html(arguments[0]);
return proxied.apply(this, arguments);
};
})();
Run Code Online (Sandbox Code Playgroud)
Esa*_*ija 40
您没有修改open继承的方法,XMLHttpRequest objects只是添加一个XMLHttpRequest constructor实际上从未使用过的方法.
我在Facebook上尝试了这个代码,我能够捕获这些请求:
(function() {
var proxied = window.XMLHttpRequest.prototype.open;
window.XMLHttpRequest.prototype.open = function() {
console.log( arguments );
return proxied.apply(this, [].slice.call(arguments));
};
})();
/*
["POST", "/ajax/chat/buddy_list.php?__a=1", true]
["POST", "/ajax/apps/usage_update.php?__a=1", true]
["POST", "/ajax/chat/buddy_list.php?__a=1", true]
["POST", "/ajax/canvas_ticker.php?__a=1", true]
["POST", "/ajax/canvas_ticker.php?__a=1", true]
["POST", "/ajax/chat/buddy_list.php?__a=1", true]
*/
Run Code Online (Sandbox Code Playgroud)
所以是的,open方法需要添加到XMLHttpRequest prototype(window.XMLHttpRequest.prototype)而不是XMLHttpRequest constructor(window.XMLHttpRequest)
这是我喜欢采取的方法;请注意,掌握 XHR 猴子补丁的黑暗艺术是一种艺术形式。
将整个套件和堆放在 IIFE 中。因此,请从以下内容开始:
(function(open, send) {
//...overrides of the XHR open and send methods are now encapsulated within a closure
})(XMLHttpRequest.prototype.open, XMLHttpRequest.prototype.send)
Run Code Online (Sandbox Code Playgroud)
使用这种通用方法可以覆盖任何方法,但是上面的脚手架为您设置了一种覆盖(又名猴子补丁)XMLHttpRequest 的 open 和 send 方法的方法;在一个简洁的实用函数中。请注意“基本”方法(来自 API 的原型对象)如何被输入 IIFE 并分配给 var 的“open”和“send”,以及如何安全地将作用域限定为功能块。
现在来谈谈胆量以及坚持你的猴子补丁的关键是什么。现在,我又这样做了,而且效果很好。
一般模式(全部在 IIFE 的范围内)是:
1) 复制方法及其参数(每个规范/原型的完整签名),
2) 放入你的模组,然后
3) 将您的 mod 应用到 XHR 原型属性,以确保所有 XHR 请求都通过您的代码。
例如,“打开”看起来像:
XMLHttpRequest.prototype.open = function(method, url, async, user, password) {
xhrOpenRequestUrl = url; // update request url, closure variable
open.apply(this, arguments); // reset/reapply original open method
};
Run Code Online (Sandbox Code Playgroud)
不要纠结于 xhrOpenRequestUrl = url; 行,此代码是从我需要 url 以便稍后处理的示例中复制的。关键要点是“open.apply”,它将您的调整巩固到 XHR open 方法中,如果您不熟悉“apply”方法或“arguments”对象,那么现在是了解它们的作用的好时机。
对于“发送”方法也类似......
XMLHttpRequest.prototype.send = function(data) {
//...what ever code you need, i.e. capture response, etc.
if (this.readyState == 4 && this.status >= 200 && this.status < 300) {
xhrSendResponseUrl = this.responseURL;
responseData = this.data; // now you have the data, JSON or whatever, hehehe!
}
send.apply(this, arguments); // reset/reapply original send method
}
Run Code Online (Sandbox Code Playgroud)
同样,“应用”至关重要,必须在所有覆盖之后完成。所以现在把它们放在一起......
(function(open, send) {
// Closure/state var's
var xhrOpenRequestUrl; // captured in open override/monkey patch
var xhrSendResponseUrl; // captured in send override/monkey patch
var responseData; // captured in send override/monkey patch
//...overrides of the XHR open and send methods are now encapsulated within a closure
XMLHttpRequest.prototype.open = function(method, url, async, user, password) {
xhrOpenRequestUrl = url; // update request url, closure variable
open.apply(this, arguments); // reset/reapply original open method
};
XMLHttpRequest.prototype.send = function(data) {
//...what ever code you need, i.e. capture response, etc.
if (this.readyState == 4 && this.status >= 200 && this.status < 300) {
xhrSendResponseUrl = this.responseURL;
responseData = this.data; // now you have the data, JSON or whatever, hehehe!
}
send.apply(this, arguments); // reset/reapply original send method
}
})(XMLHttpRequest.prototype.open, XMLHttpRequest.prototype.send)
Run Code Online (Sandbox Code Playgroud)
哦,最后一件事,你的猴子补丁反过来也可以被猴子补丁!为了尽量减少这种可能性,IIFE 代码应该位于页面中所有其他 JS 之后。至少所有可能会使用 XHR 的 JS,但在您可能针对的任何 AJAX 调用之前。此外,类似地,可以通过 Chrome 或 Web 扩展注入 XHR 猴子补丁,并且还可以覆盖您的覆盖!哈!
希望有帮助!
| 归档时间: |
|
| 查看次数: |
15521 次 |
| 最近记录: |