当离开页面时如何处理jQuery ajax post错误

36
有没有一种方法可以在JQuery中处理来自ajax请求的错误,以便当用户离开页面时,结果错误被忽略?
$(document).ready(function() {
 $.ajax( {
    url:'/server/url/',
    type: 'POST',
    data: {some..data},
    success:function(response) { do stuff with response },
    error: function(xhr, textStatus, errorThrown) {
           // Don't raise this alert if user has navigated away from the page
           alert('error');
    }
});

我很好奇是否有一种简洁的方法来处理这个问题?我知道你可以在$(window).bind("beforeunload", function(){})方法中创建一些逻辑,但我更喜欢找到一种不需要这样做的方式来处理这种情况,因为Chrome似乎不再支持它。例如,在这种情况下返回了特定的错误吗?

谢谢。


由于调用的是服务器,我认为它不会有足够的知识根据用户是否离开该页面来返回不同的响应。你能否提供此行为的示例?另一个页面的脚本在你离开该页面后继续运行似乎很奇怪。 - Will Buck
我认为脚本实际上停止运行并抛出错误,因为它被过早终止了。 - Steve Walsh
一旦您导航离开,您的 AJAX 调用将会被丢弃。客户端不再有监听器来接收来自该请求的任何消息。 - Diodeus - James MacFarlane
1
错误回调正在被调用。但是,xhr.status为0,这可能可以用于过滤此条件。 - Steve Walsh
1
可能是重复的问题:jQuery AJAX在窗口卸载时触发错误回调? - Leopd
https://bugzilla.mozilla.org/show_bug.cgi?id=768596 - 4esn0k
3个回答

19

看起来解决这个问题的方法是检查 jqXHR.status。 XMLHttpRequest 规范 概述了设置状态的步骤:

status 属性必须返回运行以下步骤的结果:

  1. 如果状态为 UNSSENT 或 OPENED,则返回 0 并终止这些步骤。

  2. 如果错误标志已设置,则返回 0 并终止这些步骤。

  3. 返回 HTTP 状态码。1

注意: 错误标志表示某种类型的网络错误或请求中止。它最初未设置,在完成状态期间使用。

因此,从我的理解来看,以下代码检查应该可以解决这个问题:

    if (xhr.status == 0)
        alert('error');

1https://web.archive.org/web/20120204040047/http://www.w3.org/TR/XMLHttpRequest/#the-status-attribute


正是我在寻找的答案。绑定新事件是过度工程化。 - eighteyes
6
有没有办法区分某人离开页面和其他网络问题(超时、主机未找到等)的情况? - Krystian Cybulski
1
这篇文章说“当响应返回时,页面已经卸载了,回调函数将不再存在”,那么错误回调函数如何可靠地工作呢? - winterlight
1
这不应该是 xhr.status == 0 吗? - user2141650
错误:function(xhr,textStatus,errorThrown){ 如果(xhr.readyState === 4) alert(error); } - nicoabie
对我无效。 对于我来说,无论是导航离开页面还是网络错误,jqXHR状态都为0,readyState也为0。 - Benedikt

14

查看状态对我没用,但是

// Ignore incomplete requests, likely due to navigating away from the page
if (jqXHR.readyState < 4) {
    return true;
} 

在错误处理程序中执行了(4已完成)。


如果服务器进程存在,则jqXHR.readyState值将为0。实际上,这应该进入错误处理,因为用户没有导航离开的情况。 - Lorenz03Tx
我不能同意。我正在使用当前版本的FireFox和jQuery v2.0.0。当我在ajax请求期间跟随链接时,ajax请求以jqXHR.readyState = 4和jqXHR.status = 404结束。 - Simon

3
我曾多次处理过这个问题。建议绑定到$(window).unload事件,在某个地方设置一些变量,比如在你的命名空间中(App.unloading = true),然后在ajax错误回调中测试它。
参见http://api.jquery.com/unload/

这似乎对所有浏览器都不起作用:http://code.google.com/p/chromium/issues/detail?id=4422 - Steve Walsh
2
请参考https://dev59.com/9HM_5IYBdhLWcg3wdy1g,了解其他方法。也许将卸载事件和标志与状态检查相结合可能足够解决问题。 - ori

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