2

我们正在绑定全局 ajax 处理程序以检查浏览器是否离线:

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

然后我们向用户显示浏览器离线的对话框,并绑定 'online' 事件以在浏览器再次在线时隐藏对话框。

是否有无论如何(甚至是一个hacky)来重新启动基于旧的Ajax请求,它适合旧的上下文?

4

2 回答 2

2

好吧,您可以使用 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开始一个新事件。XMLHTTPRequestsettingsSaved

看这个fiddle,第一次点击按钮,调用就中止了。第二次通话以旧设置开始,从那时起所有请求都正常

http://jsfiddle.net/hFmWX/

于 2012-01-13T11:02:14.110 回答
2

这是我能想到的最干净的方法:

  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)
    
于 2012-01-26T14:12:21.140 回答