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

时间:2009-05-14 08:19:53

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

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',那么IE就不会挂起。

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

3 个答案:

答案 0 :(得分:3)

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

答案 1 :(得分:2)

我对我的问题的回答。我在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 - 我的实用程序类

答案 2 :(得分:0)

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

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