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

Вопросы:

  1. Почему IE8 (и, возможно, другие ИЭ) вешают, когда пользователь пытается перейти от страницы справа после того, как выше фрагмент кода был выполнен? FireFox/Safari отменяет эти запросы и позволяет перейти на другую страницу. Если вы замените 'i < 5' на 'i < 4', тогда IE не будет висеть.

  2. Как обойти это уродливое поведение IE? Пользователи очень расстраиваются, когда их браузер внезапно зависает.

ответ

2

Мой ответ на мой вопрос. Я прерываю все не завершенные объекты 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); 

$ отлаживать - мой служебный класс

3

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

+1

предел AFAIK является 2, если они не изменили поведение по умолчанию в IE 8. Я сомневаюсь, что, потому что я довольно уверен, что RFC указывает, что «2 одновременных подключения к одному серверу». –

+1

Лучший способ понять, если это проблема, найдите связанный реестр, измените номер параллельного соединения и повторите попытку, посмотрите, все ли он зависает. –

+0

Спасибо за помощь. Что касается реестра, я знаю об этой «функции», но я не могу заставить пользователей изменять необходимые настройки в реестре на своей машине. О пределе, FireFox также имеет схожие ограничения, но он не зависает. Ограничение означает, что при достижении (пределе) дальнейшие запросы не отправляются на сервер до тех пор, пока не будет завершен какой-либо ожидающий запрос запрос, но они будут стоять в очереди и будут выполняться. Проблема с IE: если IE имеет такие _queued_ запросы, браузер зависает при навигации в сторону от страницы. – Roman

0

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

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

Смежные вопросы