【问题标题】:restart Ajax Request based on the jquery xhr object after Event: navigator.onLineEvent:navigator.onLine 之后基于 jquery xhr 对象重启 Ajax Request
【发布时间】:2012-02-09 14:10:39
【问题描述】:

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

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

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

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

【问题讨论】:

  • 与您尝试完成的实际任务无关,navigator.onLine 并不是检测与 Internet 或任何网络的连接的可靠方法。

标签: jquery ajax navigator


【解决方案1】:

你可以使用 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 事件...也许您可以使用 settingsSaved 中的值简单地开始一个新的 XMLHTTPRequest对象。

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

http://jsfiddle.net/hFmWX/

【讨论】:

  • 以及如何根据复制的xhrObj重启请求?
  • @SepOSep 我更新了我的答案,看看它是否对你有帮助
【解决方案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)
    

【讨论】:

    猜你喜欢
    • 2015-10-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-06-14
    • 2011-11-09
    • 1970-01-01
    • 2013-05-02
    相关资源
    最近更新 更多