我正在使用不同的JS库(AngularJS,OpenLayers等)构建一个Web应用程序,并且需要一种方法来拦截所有AJAX响应,以便在登录的用户会话过期(响应返回401Unauthorized状态后)的情况下重定向他到登录页面。
401Unauthorized
我知道AngularJS可以interceptors管理此类情况,但无法找到一种方法将这种注入OpenLayers请求中。因此,我选择了普通的JS方法。
interceptors
(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()以及您自己执行的任何代码,这在涉及网络调用时可能并不重要。
.open()
在IE中,这不会捕获任何试图使用ActiveXObject做Ajax的控制方法的代码。编写良好的代码将首先查找该XMLHttpRequest对象,然后使用该方法(如果可用)以及从IE7开始就可用的ActiveXObject方法。但是,可能存在一些使用该方法(如果可用)的代码,这在更高版本的IE中都是正确的。
ActiveXObject
XMLHttpRequest
在现代浏览器中,还有其他方法可以发出Ajax调用,例如fetch()接口,因此,如果要挂接所有Ajax调用,则不仅要挂接钩子XMLHttpRequest。
fetch()