如何拦截不同JS库发出的所有AJAX请求 [英] How to intercept all AJAX requests made by different JS libraries

查看:40
本文介绍了如何拦截不同JS库发出的所有AJAX请求的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在构建一个具有不同 JS 库(AngularJS、OpenLayers 等)的 Web 应用程序,并且需要一种方法来拦截所有 AJAX 响应,以防记录的用户会话过期(响应返回 401 Unauthorized 状态),将他重定向到登录页面.

I am building a web app with different JS libraries (AngularJS, OpenLayers,...) and need a way to intercept all AJAX responses to be able, in case the logged user session expired (response gets back with 401 Unauthorized status), to redirect him to the login page.

我知道 AngularJS 提供了 interceptors 来管理此类场景,但无法找到一种方法来实现对 OpenLayers 请求的这种注入.所以我选择了普通的 JS 方法.

I know AngularJS offers interceptors to manage such scenarios, but wasn't able to find a way to achieve such injection into OpenLayers requests. So I opted for a vanilla JS approach.

这里我找到了这段代码...

Here I found this piece of code...

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

...我对其进行了调整,看起来它的行为符合预期(仅在上一个 Google Chrome 上进行了测试).

...which I adapted and looks like it behaves as expected (only tested it on last Google Chrome).

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

As it modifies the prototype of XMLHTTPRequest I am wondering how dangerous this could result or if it could produce serious performance issues. And by the way would there be any valid alternative?

之前的技巧工作正常.但是,如果在相同的场景中您想在发送请求之前注入一些标头怎么办?执行以下操作:

The previous trick works ok. But what if in the same scenarion you want to inject some headers before the request gets sent? Do the following:

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

推荐答案

这种类型的函数挂钩是非常安全的,并且由于其他原因在其他方法上定期执行.

This type of function hooking is perfectly safe and is done regularly on other methods for other reasons.

而且,唯一的性能影响实际上只是每个 .open() 的一个额外函数调用以及您自己执行的任何代码,这在涉及网络调用时可能无关紧要.

And, the only performance impact is really only one extra function call for each .open() plus whatever code you execute yourself which is probably immaterial when a networking call is involved.

在 IE 中,这不会捕获任何尝试使用 ActiveXObject 控制方法执行 Ajax 的代码.编写良好的代码首先查找 XMLHttpRequest 对象,并在可用时使用它,并且自 IE 7 以来一直可用.但是,可能有一些代码使用 ActiveXObject 方法,如果它可以通过 IE 的更高版本使用.

In IE, this won't catch any code that tries to use the ActiveXObject control method of doing Ajax. Well written code looks first for the XMLHttpRequest object and uses that if available and that has been available since IE 7. But, there could be some code that uses the ActiveXObject method if it's available which would be true through much later versions of IE.

在现代浏览器中,还有其他方法可以发出 Ajax 调用,例如 fetch() 接口 所以如果你想挂接所有的 Ajax 调用,你必须挂接的不仅仅是 XMLHttpRequest.

In modern browsers, there are other ways to issue Ajax calls such as the fetch() interface so if one is looking to hook all Ajax calls, you have to hook more than just XMLHttpRequest.

这篇关于如何拦截不同JS库发出的所有AJAX请求的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆