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

IE 10 pending XMLHttpRequest for 6 minutes and then answers the request (CRSF implementation with AngularJS)

本文关键字:使用 请求 AngularJS 实现 CRSF 响应 然后 挂起 XMLHttpRequest 分钟 IE      更新时间:2023-09-26

任务描述

为我的角度应用程序实施了 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 这样的代理观察过您的网络流量?如果是这样,您可以分享流量捕获吗?