問題描述
猴子如何修補 XMLHTTPRequest
的 onreadystatechange
函數(shù).我正在嘗試添加一個函數(shù),當從頁面發(fā)出的每個 ajax 請求都返回時將調(diào)用該函數(shù).
How would go about monkey patching the XMLHTTPRequest
's onreadystatechange
function. I'm trying to add a function that would be called when every ajax request made from a page come back.
我知道這聽起來很糟糕,但用例卻很奇特.我想將某個 SDK 與控制臺 (jqconsole) 一起使用,但在控制臺中顯示 ajax 調(diào)用的狀態(tài)和結(jié)果,而無需修改外部 SDK.
I know this sounds like a terrible idea, but the use case is quite peculiar. I want to use a certain SDK with a console (jqconsole) but show status and results from ajax calls within the console without modifying the external SDK.
我查看了 這篇文章,其中包含大量信息,但沒有任何內(nèi)容猴子修補回調(diào)似乎超出了我的 JavaScript 技能.
I've looked at this post which had great info, but nothing on monkey patching the callback which seem to exceed my JavaScript skills.
P.S 不能使用 jQuery,因為它只支持由 jQuery 而不是直接來自 XMLHTTPRequests
的 ajax 調(diào)用,這里就是這種情況.
P.S Can't use jQuery since it only supports ajax calls made from jQuery not from XMLHTTPRequests
directly which is the case here.
推薦答案
要猴子補丁XMLHttpRequest
,你需要知道一個AJAX請求一般是如何構(gòu)造的:
To monkey-patch XMLHttpRequest
s, you need to know how an AJAX request is generally constructed:
- 構(gòu)造函數(shù)調(diào)用
- 準備請求(
setRequestHeader()
,open()
) - 發(fā)送請求(
.send
).
通用補丁
(function(xhr) {
function banana(xhrInstance) { // Example
console.log('Monkey RS: ' + xhrInstance.readyState);
}
// Capture request before any network activity occurs:
var send = xhr.send;
xhr.send = function(data) {
var rsc = this.onreadystatechange;
if (rsc) {
// "onreadystatechange" exists. Monkey-patch it
this.onreadystatechange = function() {
banana(this);
return rsc.apply(this, arguments);
};
}
return send.apply(this, arguments);
};
})(XMLHttpRequest.prototype);
前面假設(shè) onreadystatechange
已分配給 onreadystatechange
處理程序.為簡單起見,我沒有包含 其他事件的代碼,例如加載
.另外,我沒有考慮使用 addEventListener
添加的事件.
The previous assumed that onreadystatechange
was assigned to the onreadystatechange
handler. For simplicity, I didn't include the code for other events, such as onload
. Also, I did not account for events added using addEventListener
.
之前的補丁針對所有請求運行.但是,如果您只想將補丁限制為特定請求怎么辦?具有特定 URL 或異步標志和特定請求正文的請求?
The previous patch runs for all requests. But what if you want to limit the patch to a specific request only? A request with a certain URL or async flag and a specific request body?
示例:攔截所有請求正文中包含TEST"的POST
請求
Example: Intercepting all POST
requests whose request body contains "TEST"
(function(xhr) {
function banana(xhrInstance) { // Example
console.log('Monkey RS: ' + xhrInstance.readyState);
}
//
var open = xhr.open;
xhr.open = function(method, url, async) {
// Test if method is POST
if (/^POST$/i.test(method)) {
var send = this.send;
this.send = function(data) {
// Test if request body contains "TEST"
if (typeof data === 'string' && data.indexOf('TEST') >= 0) {
var rsc = this.onreadystatechange;
if (rsc) {
// Apply monkey-patch
this.onreadystatechange = function() {
banana(this);
return rsc.apply(this, arguments);
};
}
}
return send.apply(this, arguments);
};
}
return open.apply(this, arguments);
};
})(XMLHttpRequest.prototype);
使用的主要技術(shù)是透明重寫使用...
The main techniques used is the transparent rewrite using...
var original = xhr.method;
xhr.method = function(){
/*...*/;
return original.apply(this, arguments);
};
我的示例非常基本,可以擴展以滿足您的確切愿望.不過,這取決于您.
My examples are very basic, and can be extended to meet your exact wishes. That's up to you, however.
這篇關(guān)于猴子補丁 XMLHTTPRequest.onreadystatechange的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網(wǎng)!