![](/img/trans.png)
[英]How to intercept all AJAX(xhr and fetch) requests via javascript?
[英]How to intercept all AJAX requests made by different JS libraries
我正在构建一个具有不同 JS 库(AngularJS、OpenLayers 等)的 Web 应用程序,并且需要一种方法来拦截所有 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);
...我对其进行了调整,看起来它的行为符合预期(仅在上一个 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);
这种类型的函数挂钩是完全安全的,并且由于其他原因在其他方法上定期执行。
而且,唯一的性能影响实际上只是每个.open()
额外函数调用以及您自己执行的任何代码,这在涉及网络调用时可能无关紧要。
在 IE 中,这不会捕获任何尝试使用ActiveXObject
控件方法执行 Ajax 的代码。 编写良好的代码首先查找XMLHttpRequest
对象,并在可用时使用该对象,并且自 IE 7 以来一直可用。但是,可能有一些代码使用ActiveXObject
方法(如果它可用),这在 IE 的更高版本中是正确的。
在现代浏览器中,还有其他方法可以发出 Ajax 调用,例如fetch()
接口,因此如果要挂钩所有 Ajax 调用,则必须挂钩的不仅仅是XMLHttpRequest
。
对于某些版本的 IE (9 及以下),这不会捕获 XMLHttpRequests。 根据库,他们可能会首先查找 IE 的专有 ActiveX 控件。
而且,当然,如果您在 IE 下使用非严格的 DOCTYPE,那么所有的赌注都会被取消,但我相信您知道这一点。
参考: CanIuse
正如 Firefox AMO 编辑Rob W
亲切指出的那样,
以下代码更改 XMLHttpRequest 的行为。 默认情况下,如果未指定第三个(“async”)参数,则默认为 true。 当它被指定和未定义时,它相当于“false”,它将一个请求变成一个同步的 HTTP 请求。 这会导致 UI 在处理请求时阻塞,并且 XMLHttpRequest API 的某些功能也被禁用。
...
要解决此问题,请将 open.call(....) 替换为 open.apply(this, arguments);
这是一个参考链接:
尝试这个
let oldXHROpen = window.XMLHttpRequest.prototype.open;
window.XMLHttpRequest.prototype.open = function(method, url, async, user, password) {
console.log({method});
// Show loader
this.addEventListener('load', function() {
console.log('load: ' + this.responseText);
// Hide loader
});
return oldXHROpen.apply(this, arguments);
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.