在 Event: navigator.onLine 之后重新启动基于 jquery xhr 对象的 Ajax 请求

发布于 2024-12-26 09:38:24 字数 308 浏览 3 评论 0原文

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

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

然后我们向用户显示一个对话框,表明浏览器已离线,并绑定“在线”事件,以便在浏览器再次上线时隐藏该对话框。

是否有无论如何(即使是一个 hacky)根据旧的适合旧上下文的旧 Ajax 请求重新启动 Ajax 请求?

We are binding global ajax handlers to check if the browser went offline :

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

then we are showing a dialog to the user that the browser went offline and bind for the 'online' event to hide the dialog when the browser turns online again.

Is there Anyway (even a hacky one) to restart the Ajax request based on the old which fits in the old context?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

鹿! 2025-01-02 09:38:24

这是我能想到的最简洁的方法:

  1. 用于缓存 AJAX 请求设置的队列,以便每个后续调用都不会覆盖前一个
  2. ajaxSend() 处理程序中的条件,用于推送调用放在队列中以供稍后使用或执行整个队列。

    !(函数($, 窗口, 未定义){
        var ajaxRequestQueue = [], // 离线时发出的请求队列
            isProcessingQueue = false;
    
        函数 processRequestQueue() {
            if (isProcessingQueue === true)
            {
                返回;
            }
    
            isProcessingQueue = true;
            while (设置 = ajaxRequestQueue.shift())
            {
                $.ajax(设置);
            }
            isProcessingQueue = false;
        }
    
        $(文档).ajaxSend(函数(事件、xhr、设置、响应){
            if (!navigator.onLine) {
                // 中止原来的请求
                xhr.abort();
                // 将请求设置的副本推送到队列上
                ajaxRequestQueue.push($.extend(true, {}, settings));
            }
            否则如果(ajaxRequestQueue.length > 0
                 && isProcessingQueue === false)
            // 队列中有调用,我们自己还没有触发“ajaxSend”
            {
                处理请求队列();
            }
        });
    
        // 绑定以在浏览器重新上线时开始处理队列
        window.addEventListener("在线", processRequestQueue);
    })(jQuery,窗口)
    

Here's the cleanest approach I can think of:

  1. A queue for caching AJAX request settings so each subsequent call doesn't overwrite the previous one
  2. A conditional in the ajaxSend() handler that either pushes the calls on the queue for later or executes the entire queue.

    !(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)
    
生寂 2025-01-02 09:38:24

好吧,你可以使用 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/

Well you might clone the object using jQuery and then restart your call when the browser goes back online

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

don't know if this really works, you could try it

EDIT - Ok i tried it and no way, you can't call send() on that object. This is because xhr is not the original request but a 'fake' object created by jQuery
A different approach might be this one: You save the settings object and then you start another $.ajax call with
those settings.
Basically you do

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();
    }
}

Be really careful that this requre an accurate flow control because every time you call $.ajax you trigger another ajaxSend event...maybe you could simply start off a new XMLHTTPRequest using the values from the settingsSaved object.

Look at this fiddle, the first time you click a button, the call is aborted. The second time the call starts with the old settings and from then on all requests are normal

http://jsfiddle.net/hFmWX/

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文