javascript - 猴子补丁 XMLHTTPRequest.onreadystatechange

标签 javascript ajax xmlhttprequest monkeypatching

猴子如何修补 XMLHTTPRequestonreadystatechange 函数。我正在尝试添加一个函数,当从页面发出的每个 ajax 请求返回时都会调用该函数。

我知道这听起来很糟糕,但用例非常特殊。我想将某个 SDK 与控制台 (jqconsole) 一起使用,但在不修改外部 SDK 的情况下显示控制台内 ajax 调用的状态和结果。

我看过this post它有很好的信息,但没有关于猴子修补回调的信息,这似乎超出了我的 JavaScript 技能。

P.S 不能使用 jQuery,因为它只支持从 jQuery 发出的 ajax 调用,而不是直接从 XMLHTTPRequests 发出的 ajax 调用,这里就是这种情况。

最佳答案

要猴子修补 XMLHttpRequest,您需要知道 AJAX 请求的一般构造方式:

  1. 构造函数调用
  2. 准备请求(setRequestHeader(), open())
  3. 发送请求(.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);

前面假定 onreadystatechange 已分配给 onreadystatechange 处理程序。为简单起见,我没有包含 other events 的代码,例如 onload。此外,我没有考虑使用 addEventListener 添加的事件。

之前的补丁针对所有请求运行。但是,如果您只想将补丁限制为特定请求怎么办?具有特定 URL 或异步标志和特定请求正文的请求?

条件猴子补丁

示例:拦截所有请求正文包含“TEST”的POST请求

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

使用的主要技术是使用...的透明重写

var original = xhr.method; 
xhr.method = function(){
    /*...*/;
    return original.apply(this, arguments);
};

我的示例非常基础,可以扩展以满足您的确切需求。不过,这取决于您。

关于javascript - 猴子补丁 XMLHTTPRequest.onreadystatechange,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12575572/

相关文章:

javascript - JavaScript 中的 CAML 以检索 SharePoint 留言板中的所有项目

javascript - document.getSelection 在选择中带有回车符

javascript - 异步函数调用是否可以在两个同步语句之间完成?

即使 cors = true,Jquery ajax 也无法在 IE9 中工作

python - 使用日期范围迭代一系列带日期标记的 XHR 请求

rest - OPTIONS 请求使用 CORS 进行 Restful 跨域

javascript - 我正在尝试制作一个随机单词生成器,为什么在我添加一个将数字转换为文本的开关后它不会更新 html?

javascript - 如何在 Flask 中使用 JSON 对象

javascript - XMLHttpRequest 仅在 Internet Explorer 中花费很长时间

javascript - 创建 Stripe 的 Mock 还是在 Stripe 对象上使用 Stub?