Javascript IE 10挂起XMLHttpRequest 6分钟,然后回答请求(使用AngularJS实现CRSF)

Javascript IE 10挂起XMLHttpRequest 6分钟,然后回答请求(使用AngularJS实现CRSF),javascript,angularjs,security,internet-explorer,xmlhttprequest,Javascript,Angularjs,Security,Internet Explorer,Xmlhttprequest,任务描述 我为我的角度应用程序实现了CRSF保护。服务器检查crsf令牌是否放置在请求的标头“X-CSRF-token”中。如果不是,则发送http响应403 Ï在我的客户机上,我截获所有请求并检查是否返回http响应403。在这种情况下,我发送一个HEAD请求,以便从服务器获取crsf令牌,该令牌在响应的头“X-CSRF-token”中返回 从服务器获取令牌后,我使用头“X-CSRF-token”中给定的crsf令牌重新发送原始请求 问题描述 这适用于除internet explorer(IE

任务描述

我为我的角度应用程序实现了CRSF保护。服务器检查crsf令牌是否放置在请求的标头“X-CSRF-token”中。如果不是,则发送http响应403

Ï在我的客户机上,我截获所有请求并检查是否返回http响应403。在这种情况下,我发送一个HEAD请求,以便从服务器获取crsf令牌,该令牌在响应的头“X-CSRF-token”中返回

从服务器获取令牌后,我使用头“X-CSRF-token”中给定的crsf令牌重新发送原始请求

问题描述

这适用于除internet explorer(IE9和IE10)之外的所有浏览器。在本地(没有代理和防火墙),它也可以与internet explorer一起使用。但在我们的生产环境中,head请求在360s内处于挂起状态,但随后返回预期的响应

我不知道发生了什么事。为什么它可以在本地主机上工作,但不能在生产环境中工作?这可能是代理的问题吗?但为什么它能与所有其他浏览器(chrome、firefox等)协同工作呢?即使在6分钟后,IE也会得到正确的答案,并按预期进行。对我来说,这看起来不像是代理问题。所以,这是IE的问题吗?但为什么它在本地主机上工作

IE和其他浏览器请求的唯一区别是标题中的referer: -在IE中,推荐人看起来像 -在其他浏览器中,referer看起来像

本地环境和生产环境之间的区别在于,代理截获请求并进行一些上下文重写,并打开https隧道。服务器实际上使用http,然后代理通过隧道传输请求

有人知道问题出在哪里吗

这是我的angular模块,它注册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;
                     }
                 };
             });
         });
 })();
“严格使用”;
(功能(){
角度模块('csrf-token-interceptor',[])
.config(函数($httpProvider){
var csrfToken={headerName:'X-CSRF-TOKEN',TOKEN:null};
var getCsrfToken=函数(){
var xhr=new XMLHttpRequest();
xhr.open('head','/context root/index.html?id='+new Date().toString(),false);
xhr.send();
返回{headerName:'X-CSRF-TOKEN',TOKEN:xhr.getResponseHeader('X-CSRF-TOKEN');
};
var numRetries=0;
var MAX_重试次数=1;
$httpProvider.interceptors.push(函数($q,$injector){
返回{
请求:函数(配置){
config.headers[csrfToken.headerName]=csrfToken.token;
返回配置| |$q.when(配置);
},
responseError:函数(响应){
if(response.status==403&&numRetries
请求内容如下:

  • 帖子,时间:53ms,状态:403
  • 头部…,时间:360,2s,状态:200
  • 帖子,时间:49ms,状态:200
这可能是IE中的一个bug,与您使用
HEAD
方法有关;看


您是否使用类似Fiddler的代理来观察网络流量?如果是这样,您可以共享流量捕获吗?

我将请求添加到问题中,您添加的请求没有显示HTTP版本号,这将显示这是否是已知的IE错误。抱歉,我没有正确阅读您的答案。这确实可能是问题所在。它在本地使用HTTP/1.1,在生产环境中使用HTTP/1.0。代理似乎正在使用HTTP/1.0。我将尝试bug报告中提供的解决方案,然后分享它是否有效。您能否以更有用的格式(例如Fiddler
.SAZ
或HTTP Archive
.har
)分享请求?