IE 10 挂起 XMLHttpRequest 6 分钟,然后响应请求(使用 AngularJS 实现 CRSF)
IE 10 pending XMLHttpRequest for 6 minutes and then answers the request (CRSF implementation with AngularJS)
任务描述
我为我的角度应用程序实施了 CRSF 保护。服务器检查 crsf 令牌是否放置在请求的标头"X-CSRF-TOKEN"中。如果不是,则发送http响应403。
在我的客户端中,我拦截所有请求并检查是否返回 http 响应 403。在这种情况下,我发送一个HEAD请求,以便从服务器获取crsf令牌,该令牌在响应的标头"X-CSRF-TOKEN"中返回。
从服务器获取令牌后,我在标头"X-CSRF-TOKEN"中使用给定的 crsf 令牌重新发送原始请求。
问题描述
这适用于所有浏览器,除了Internet Explorer(尝试IE 9和10)。在本地(没有代理和防火墙),它也可以与Internet Explorer一起使用。但是在我们的生产环境中,head 请求在 360 秒内处于挂起状态,但随后返回预期的响应。
我不确定发生了什么。为什么它在本地主机上工作,但在生产环境中不起作用?可能是代理的问题吗?但是为什么它适用于所有其他浏览器(chrome,火狐等)?即使在 6 分钟后,IE 也会得到正确答案并按预期进行。对我来说,这看起来不像是代理问题。那么,这是IE的问题吗?但是为什么它在本地主机上工作?
IE和其他浏览器的请求的唯一区别是标头中的引用器: - 在IE中,引用看起来像 http://url/context-root/#/login - 在其他浏览器中,引用看起来像 http://url/context-root/
本地环境和生产环境之间的区别在于,代理拦截请求并进行一些上下文重写并打开 https 隧道。服务器实际上使用 http,然后代理通过隧道传输请求。
有谁知道问题可能是什么?
这是我的角度模块,它注册了http拦截器:
'use strict';
(function () {
angular.module('csrf-token-interceptor', [])
.config(function ($httpProvider) {
var csrfToken = { headerName: 'X-CSRF-TOKEN', token: null };
var getCsrfToken = function () {
var xhr = new XMLHttpRequest();
xhr.open('head', '/context-root/index.html?id=' + new Date().toString(), false);
xhr.send();
return { headerName: 'X-CSRF-TOKEN', token: xhr.getResponseHeader('X-CSRF-TOKEN') };
};
var numRetries = 0;
var MAX_RETRIES = 1;
$httpProvider.interceptors.push(function ($q, $injector) {
return {
request: function (config) {
config.headers[csrfToken.headerName] = csrfToken.token;
return config || $q.when(config);
},
responseError: function (response) {
if (response.status === 403 && numRetries < MAX_RETRIES) {
csrfToken = getCsrfToken();
var $http = $injector.get('$http');
++numRetries;
return $http(response.config);
}
return $q.reject(response);
},
response: function(response) {
numRetries = 0;
var newToken = response.headers(csrfToken.headerName);
if (newToken !== null) {
csrfToken.token = newToken;
}
return response;
}
};
});
});
})();
这些请求如下所示:
- 开机自检 http://url/context-root/#/login,时间:53ms,状态:403
- 头 http://url/context-root/index.html?id=..., 时间: 360,2秒, 状态: 200
- 开机自检 http://url/context-root/#/login, 时间: 49ms, 状态: 200
这可能是 IE 中与您使用 HEAD
方法相关的错误;请参阅 https://connect.microsoft.com/IE/feedback/details/1023203/xhr-readystate-done-delay-on-head-request
您是否使用像 Fiddler 这样的代理观察过您的网络流量?如果是这样,您可以分享流量捕获吗?
- 使用请求对象中可用的值打印 JavaScript 警报
- Node.js:无法使用请求模块进行PROFIND
- 使用Google Drive和Angularjs时,不允许使用请求标头字段Accept Encoding
- 使用请求NPM包返回带有嵌套函数的值
- 如何使用请求 npm 模块判断 http 请求是否完成
- 在 Python 中使用请求获取页面但不使用源代码,为什么?如何获取源代码
- 如何发出许多 Node.js 请求(使用请求模块)
- Django View 无法使用请求获取文件.来自 ajax 表单的文件提交
- 在摩卡中使用请求调用测试函数
- 使用请求-承诺的嵌套异步请求
- 使用请求参数从 JavaScript 调用 servlet
- 如何使用请求动画帧暂停和重新启动秒表计时器
- 无法使用请求模块处理 url
- 如何使用javascript使用请求中的属性
- 如何在node.js Express中的async.each中使用请求
- 使用请求模块nodejs下载文件时需要filename
- 我如何使用请求库和蓝鸟发送post请求
- 如何在遵循以下模式的代码中使用请求动画帧
- 使用请求.对象作为另一个类的parentObject在afterSave
- 文件结构的最佳实践-使用请求模块(Node.js + Express.js)