如何拦截不同JS库所做的所有AJAX请求

met*_*jus 106 javascript ajax interceptor

我建立与不同的JS库的web应用程序(AngularJS,的OpenLayers,...),并需要一种方法来拦截所有AJAX响应,以便能够在情况下登录的用户会话超时(响应回来与401 Unauthorized地位),重定向他到登录页面.

我知道AngularJS提供interceptors管理此类方案,但无法找到实现此类注入OpenLayers请求的方法.所以我选择了一种香草JS方法.

在这里,我发现了这段代码......

(function(open) {

    XMLHttpRequest.prototype.open = function(method, url, async, user, pass) {

        this.addEventListener("readystatechange", function() {
            console.log(this.readyState); // this one I changed
        }, false);

        open.call(this, method, url, async, user, pass);
    };

})(XMLHttpRequest.prototype.open);
Run Code Online (Sandbox Code Playgroud)

...我改编并看起来像预期的那样(仅在最后一个Google Chrome上测试过).

当它修改XMLHTTPRequest的原型时,我想知道这可能导致多么危险,或者它是否会产生严重的性能问题.顺便说一句,有没有有效的替代方案?

更新:如何在发送请求之前拦截请求

上一个技巧可行.但是如果在同一个场景中你想在发送请求之前注入一些标题呢?请执行下列操作:

(function(send) {

    XMLHttpRequest.prototype.send = function(data) {

        // in this case I'm injecting an access token (eg. accessToken) in the request headers before it gets sent
        if(accessToken) this.setRequestHeader('x-access-token', accessToken);

        send.call(this, data);
    };

})(XMLHttpRequest.prototype.send);
Run Code Online (Sandbox Code Playgroud)

jfr*_*d00 34

这种类型的功能挂钩非常安全,并且由于其他原因定期在其他方法上完成.

并且,唯一的性能影响实际上只是一个额外的函数调用,每个.open()加上你自己执行的任何代码,这在涉及网络调用时可能并不重要.


在IE中,这将不会捕获任何试图使用ActiveXObjectAjax控制方法的代码.编写良好的代码首先查找该XMLHttpRequest对象并使用该代码(如果可用)并且自IE 7以来一直可用.但是,如果可用的话,可能会有一些代码使用该ActiveXObject方法,这对于IE的更高版本来说是正确的.


在现代浏览器中,还有其他方法可以发出Ajax调用,例如fetch()接口,所以如果有人想要挂钩所有Ajax调用,你必须更多地挂钩XMLHttpRequest.