【问题标题】:IE8 hangs when more than 4 async XmlHttpRequests are triggered concurrently当同时触发超过 4 个异步 XmlHttpRequest 时,IE8 挂起
【发布时间】:2010-10-26 02:50:54
【问题描述】:
for (var i = 0; i < 5; ++i) {
  var xhr;
  if (window.XMLHttpRequest) {
    xhr = new XMLHttpRequest();
  } else if (window.ActiveXObject) {
    xhr = new ActiveXObject("Msxml2.XMLHTTP");
  }
  xhr.open('GET', '/Test/LongOperation?p=' + new Date());
  xhr.send('');
}

这只是一个演示(不是实时代码),但它说明了核心问题。 LongOperation是10秒后返回结果的方法。

问题:

  1. 为什么当用户在上面的代码 sn-p 执行后试图离开页面时,IE8(可能还有其他 IE)会挂起? FireFox/Safari 取消这些请求并允许导航到另一个页面。如果将'i &lt; 5' 替换为'i &lt; 4',则IE 不会挂起。

  2. 如何解决这种丑陋的 IE 行为?当他们的浏览器突然挂起时,用户非常沮丧。

【问题讨论】:

    标签: ajax internet-explorer internet-explorer-8 xmlhttprequest


    【解决方案1】:

    大多数浏览器对任何给定服务器的连接限制为 4 个。解决此“问题”的一种方法可能是对带外 XML 请求使用不同的主机名 - 您的用户请求将发送到主主机,而 AJAX 请求可以发送到第二个服务器。

    【讨论】:

    • AFAIK 限制为 2,除非他们更改了 IE 8 中的默认行为。我对此表示怀疑,因为我很确定 RFC 表明“2 个并发连接到一台服务器。”
    • 最好了解是否是这个问题,找到相关注册表更改并发连接数重试,看看是否仍然挂起。
    • 感谢您的帮助。关于注册表,我知道这个“功能”,但我不能强迫用户在他们的机器上更改注册表中的必要设置。关于限制,FireFox 也有类似的限制,但不会挂起。限制意味着当达到它(限制)时,在完成一些待处理的请求之前不会向服务器发送更多请求,但它们排队并且执行。问题在于 IE:如果 IE 有这样的 queued 请求,浏览器在离开页面时会挂起。
    • 对于非调制解调器用户,IE8 中的限制已更改为 6。但是,当您说“挂起”时,我怀疑您实际上是指“保持响应但不导航到同一服务器上的页面,而是进度甜甜圈只是旋转”?
    【解决方案2】:

    尝试异步运行它们,然后在每个完成时触发下一个 http 请求。我怀疑 xmlhttp 请求阻塞了 IE 的 UI 线程,而在其他浏览器上的实现更优雅一些。

    希望这将为您提供问题 2 的解决方法,但我只能猜测问题 1 的真正原因,它可能只是一个错误。

    【讨论】:

      【解决方案3】:

      我对我的问题的回答。我中止了 window.onbeforeunload 中所有未完成的 xhr 对象。至少这个解决方案对我有用。我稍微重写了 $.ajax() 方法的行为:

      ;(function($) {
          var rq = [];
          var ajax = $.ajax;
          $.ajax = function(settings) {
              // override complete() operation
              var complete = settings.complete;
              settings.complete = function(xhr) {
                  if (xhr) {
                      // xhr may be undefined, for example when downloading JavaScript
                      for (var i = 0, len = rq.length; i < len; ++i) {
                          if (rq[i] == xhr) {
                              // drop completed xhr from list
                              rq.splice(i, 1);
                              break;
                          }
                      }
                  }
                  // execute base
                  if (complete) {
                      complete.apply(this, arguments)
                  }
              }
      
              var r = ajax.apply(this, arguments);
              if (r) {
                  // r may be undefined, for example when downloading JavaScript
                  rq.push(r);
              }
              return r;
          };
      
          // 'kill' all pending xhrs
          $(window).bind('beforeunload', function() {
              $.each(rq, function(i, xhr) {
                  try {
                      xhr.abort();
                  } catch(e) {
                      $debug.fail('failed to abort xhr');
                  }
              });
              rq = [];
          });
      })(jQuery);
      

      $debug - 我的实用程序类

      【讨论】:

        猜你喜欢
        • 2015-10-28
        • 1970-01-01
        • 2021-03-23
        • 1970-01-01
        • 1970-01-01
        • 2020-10-11
        • 1970-01-01
        • 1970-01-01
        • 2020-03-05
        相关资源
        最近更新 更多