代码之家  ›  专栏  ›  技术社区  ›  Roman

当同时触发超过4个异步XmlHttpRequests时,IE8挂起

  •  3
  • Roman  · 技术社区  · 17 年前
    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. 为什么IE8(可能还有其他IE)在用户试图在执行上述代码段后立即离开页面时挂起?FireFox/Safari取消这些请求并允许导航到其他页面。如果你更换 'i < 5' 'i < 4' 那我就不挂了。

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

    3 回复  |  直到 17 年前
        1
  •  3
  •   1800 INFORMATION    17 年前

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

        2
  •  2
  •   Roman    16 年前

    我对我的问题的回答。我在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);
    

        3
  •  0
  •   Neil Trodden    17 年前

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

    希望这能让你解决问题2,但我只能猜测问题1的真正原因,它可能只是一个bug。