Заблокированные и ожидающие запросы ajax от JQuery в Chrome

Время от времени мои Ajax-вызовы (через JQuery 1.8) в моем приложении задерживаются со статусом "ожидание" в течение длительного времени (иногда до 17 минут). Я искал его, и все возможные решения не работали:

  • У меня нет блокировщика рекламы.
  • Я отключил флаг "предсказывать сетевые действия для повышения производительности загрузки страницы" в Chrome.
  • Я также добавил строку запроса к вызову Ajax, чтобы сделать его уникальным (чтобы отключить блокировку кеша Chrome).

Есть ли у вас какая-либо идея, как это решить? Спасибо.

В приведенном ниже примере запрос находился на рассмотрении в течение 17 минут (проверено с помощью Fiddler, что оно было отправлено только через 17 минут).

   GET http://www.mywebsite.com/foo/rest/publishers/1/packages?_=1421584749323    HTTP/1.1
   Host: www.mywebsite.com
   Connection: keep-alive
   Accept: application/json, text/javascript, */*; q=0.01
   X-Requested-With: XMLHttpRequest
   User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36    (KHTML, like Gecko) Chrome/39.0.2171.99 Safari/537.36
   Content-Type: application/json
   Referer: http://www.mywebsite.com/foo/client/home
   Accept-Encoding: gzip, deflate, sdch
   Accept-Language: en-US,en;q=0.8,he;q=0.6,ru;q=0.4
   Cookie: JSESSIONID=C668509B5AFCDEBE9C9774C4721AFB9D;
   aaassz="ddss"

Смотрите изображение: https://drive.google.com/file/d/0B9uQiZLJG1csNzlPcHZEWHl1Z2c/view

Ответы

Ответ 1

Я наткнулся на ту же проблему. Как только я отключился:

Использование службы прогнозирования для более быстрой загрузки страниц

Go Дополнительные настройки → Конфиденциальность → ca. 3rd checkbox, все приступило к работе так, как должно быть. Я не смог воспроизвести ошибку.

Полтер jquery/ajax отлично работает в Firefox. Это только Chrome - проверено на Linux и Windows.

Это не идеальное решение, так как оно не повлияет на пользователей в глобальном смысле, но, возможно, вы находитесь в той же ситуации, что и я - ограниченная аудитория.

Ответ 2

Вы можете попробовать это.

СЕЙЧАС ОБНОВЛЕНО С ФАКТИЧЕСКИМ РАБОЧИМ КОДОМ

(использовал некоторый код часового пояса, чтобы оправдать ссылки на часовой пояс)

Сначала инициализируйте массивы и запустите логику подсчета запросов

var request = ( typeof request != 'undefined' && request instanceof Array ) ? request : [];
var pendingAjax = ( typeof pendingAjax != 'undefined' && pendingAjax instanceof Array ) ? pendingAjax : [];

Используйте . ajaxStart и . ajaxStop, чтобы отслеживать активных запросов.

var ajaxActive = 0;
$( document ).ajaxStart(function() {
  ajaxActive++;
  document.ajaxQueueFull = ajaxActive > 5;
});
$(document).ajaxStop(function() {
  ajaxActive--;
  document.ajaxQueueFull = ajaxActive > 5;
}

Создать функцию для создания новых запросов

    function ajaxRequestNew(t, u, d, s) {

        var instance = request.length + 1;
        request[instance] = $.ajax({
            method: t,
            url: u,
            data: {ajaxPost: d },
            success: s
        });
        return instance;
    }

Теперь создайте свой запрос, получив возвращаемый номер экземпляра

    var instance = ajaxRequestNew('POST', 
                                  'js/ajax_timezone.php', 
                                  { ajaxAction : "ajaxGetTimezone", 
                                    tzoffset : "0", 
                                    tztimezone: "America/New_York" },
                                    function(data) {  }
    );

Функция $.ajax() возвращает объект XMLHttpRequest. Поэтому мы используем цикл while для проверки того, когда наш аякс фактически отправляется и прерывает другие активные запросы, если запрос застопорился.

    while(request[instance] === null || (request[instance].readyState < 1 || request[instance].readyState > 4)) {
        if (document.ajaxQueueFull) {
            //abort existing requests
            $.each(request, function(i,v) {
                if (i !== instance) {
                    request[i].abort();
                }
            });
        }
    }

Вставьте ваш запрос в стек

    pendingAjax.push(request[instance]);

Создайте обратные вызовы для вашего запроса

  var timezoneFailCallback = function(data) {
        console.log('fail');
        console.dir(data);
    };

    var timezoneSuccessCallback = function(data) {
        console.log('success');
        console.dir(data);
    };

использовать, когда применять обратные вызовы

    $.when.apply($, pendingAjax).done( timezoneSuccessCallback ).fail( timezoneFailCallback);

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