перезапустите Ajax-запрос на основе объекта jquery xhr после Event: navigator.onLine - PullRequest
2 голосов
/ 13 января 2012

Мы связываем глобальные обработчики ajax, чтобы проверить, не отключился ли браузер:

$(document).ajaxSend(function(event, xhr, settings, response){  
   if(!navigator.onLine){  
        xhr.abort();  
   }  
}

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

Есть ли способ (даже хакерский) перезапустить запрос Ajax на основе старого, который соответствует старому контексту?

Ответы [ 2 ]

2 голосов
/ 26 января 2012

Вот самый чистый подход, который я могу себе представить:

  1. Очередь для кэширования настроек запроса AJAX, чтобы каждый последующий вызов не переписывал предыдущий
  2. Условныйв обработчике ajaxSend(), который либо отправляет вызовы в очередь на более поздний срок, либо выполняет всю очередь.

    !(function($, window, undefined){
        var ajaxRequestQueue  = [],    // queue for requests that were made while offline
            isProcessingQueue = false;
    
        function processRequestQueue() {
            if (isProcessingQueue === true)
            {
                return;
            }
    
            isProcessingQueue = true;
            while (settings = ajaxRequestQueue.shift())
            {
                $.ajax(settings);
            }
            isProcessingQueue = false;
        }
    
        $(document).ajaxSend(function(event, xhr, settings, response){
            if (!navigator.onLine) {
                // abort the original request
                xhr.abort();
                // push a copy of the request's settings on the queue
                ajaxRequestQueue.push($.extend(true, {}, settings));
            }
            else if (ajaxRequestQueue.length > 0
                 && isProcessingQueue        === false)
            // there are calls on queue and we haven't triggered 'ajaxSend' ourselves
            {
                processRequestQueue();
            }
        });
    
        // Bind to start processing the queue when the browser comes back online
        window.addEventListener("online", processRequestQueue);
    })(jQuery, window)
    
2 голосов
/ 13 января 2012

Что ж, вы можете клонировать объект с помощью jQuery, а затем перезапустить вызов, когда браузер вернется в режим онлайн

// Deep copy
var savedXhr= jQuery.extend(true, {}, xhr);

не знаю, действительно ли это работает, вы можете попробовать

РЕДАКТИРОВАТЬ - Хорошо, я попробовал это и ни в коем случае, вы не можете вызвать send () для этого объекта. Это связано с тем, что xhr - это не исходный запрос, а «поддельный» объект, созданный jQuery. Другой подход может быть таким: вы сохраняете объект настроек, а затем начинаете еще один вызов $ .ajax с помощью эти настройки. В основном вы делаете

var settingsSaved;

$(document).ajaxSend(function(event, xhr, settings, response) {
    if (!navigator.onLine) {
        settingsSaved = jQuery.extend(true, {}, settings);
        xhr.abort();
    } else {
        //Send the request with the old settings
        $.ajax(settingsSaved);
        //abort the new request
        xhr.abort();
    }
}

Будьте очень осторожны, чтобы получить точное управление потоком, потому что каждый раз, когда вы вызываете $ .ajax, вы запускаете другое событие ajaxSend ... возможно, вы могли бы просто запустить новый XMLHTTPRequest, используя значения из settingsSaved объект.

Посмотрите на эту скрипку, при первом нажатии кнопки звонок прерывается. Второй раз звонок начинается со старых настроек и с этого момента все запросы в норме

http://jsfiddle.net/hFmWX/

...