jQuery:如何在页面卸载时自动中止Ajax请求?

13

感谢阅读。

我注意到,如果我有一个页面打开了一个或多个ajax请求,并且我点击一个链接离开这个页面,或者刷新它,它会等待ajax请求完成才能卸载。

通常情况下这不是问题,但如果请求需要一段时间,则可能会成为问题。

我正在寻找类似于:

$(window).bind("beforeunload", function() {AjaxRequest.abort();});

想要在页面unload之前自动中止请求,但是不确定如何找到ajax请求。它们会在window下面吗?

5个回答

10

$.ajax() jQuery方法返回XMLHttpRequest对象。这意味着可以在该对象上应用标准方法,例如abort()。

要卸载,请使用内置的unload jQuery事件方法。

var myajax = $.ajax(...); 
$(window).unload( function () { myajax.abort(); } );

我遇到了一个JS错误:“myajax.abort”不是一个函数(jQuery 1.3.2)。有人驯服过“中止兽”吗? - taber
编辑:我想这是因为我在 $.ajax(...) 调用的末尾使用了 ".responseText"。我去掉了 .responseText,现在没有错误了。耶。 - taber
Jquery中的unload方法已被删除 :/ - Badiparmagi

8
以下代码已在Chrome中测试,并可在页面卸载时终止所有未完成的jQuery ajax请求,但使用Edge和IE客户端时也同样没有错误。
将以下代码作为第一个jQuery ready处理程序:
$(onPageLoaded)

并将此放在易于访问的位置:

function onPageLoaded() {
    var jqxhrs = [];

    $(window).bind("beforeunload", function (event) {
        $.each(jqxhrs, function (idx, jqxhr) {
            if (jqxhr)
                jqxhr.abort();
        });
    });

    function registerJqxhr(event, jqxhr, settings) {
        jqxhrs.push(jqxhr);
    }

    function unregisterJqxhr(event, jqxhr, settings) {
        var idx = $.inArray(jqxhr, jqxhrs);
        jqxhrs.splice(idx, 1);
    }

    $(document).ajaxSend(registerJqxhr);
    $(document).ajaxComplete(unregisterJqxhr);
};

这个很好用。如果你在记录控制台错误等信息,请确保测试textStatus!='abort',因为你的ajax error函数仍然会被调用以处理中止。 - dhc
我已经添加了最新版本。原始代码中有一个while()循环,只有当没有xhr对象时才退出。然而,这会在列表中找到空的xhr条目,并在某些情况下出错。 - yourpublicdisplayname
抱歉打扰了。您的意思是将以下内容作为第一个jQuery ready处理程序,然后像这样使用它 => $(onPageLoaded).ready(...) ? - Another Weeb

4
我刚遇到了这个问题,我在PHP中执行了一个长循环,这个循环是从$.ajax调用的。我的解决方案是在长循环之前添加session_write_close();。
我的理论是,Chrome在取消任何后台ajax请求之前会请求下一页。如果您的ajax请求与您正在导航离开和进入的页面具有相同的_SESSION,则即使您的第一行PHP代码还没有被执行,您也会遇到死锁。

2

您需要持续所有的ajax请求,并在页面重新加载时中止所有请求。示例:

var _requests = [];

var _abortAllRequests = function () {
    $(_requests).each(function (i, xhr) { xhr.abort(); });

    _requests = [];
}

$(window).on("beforeunload", function () { 
    _abortAllRequests();
});

在你的代码中的某个地方

 _requests.push($.ajax(...))

此外,您可以使用$.ajaxSetup与事件ajaxStart ajaxStop来弹出已完成的请求,但这取决于您。

1

你可能需要使用window.onunload事件以及每个请求的AjaxRequestX = $.get(...),也许将对象保存在数组中,在卸载时遍历它们。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接