IE8 зависает, когда более чем 4 асинхронных XmlHttpRequests запускаются одновременно - PullRequest
3 голосов
/ 14 мая 2009
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 ]

3 голосов
/ 14 мая 2009

Большинство браузеров имеют встроенный лимит в 4 подключения к любому серверу. Одним из способов обойти эту «проблему» может быть использование другого имени хоста для внешних XML-запросов - ваши пользовательские запросы будут отправляться на основные хосты, а запросы AJAX могут передаваться на второй сервер.

2 голосов
/ 15 мая 2009

Мой ответ на мой вопрос. Я отменяю все незавершенные объекты xhr в window.onbeforeunload. По крайней мере, это решение работает для меня. Я слегка переопределяю поведение метода $ .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 - мой служебный класс

0 голосов
/ 14 мая 2009

Попробуйте запустить их асинхронно и затем запустить следующий http-запрос, когда каждый из них завершится. Я подозреваю, что запрос xmlhttp блокирует поток пользовательского интерфейса IE, в то время как реализации этого в других браузерах немного более изящны.

Надеюсь, это даст вам обходной путь к вопросу 2, но я могу только догадываться об истинной причине вопроса 1, это может быть просто ошибка.

...