jQuery AJAX在窗口卸载时触发错误回调 – 如何过滤掉卸载并仅捕获真正的错误?

如果我离开$ .ajax()请求中间的页面,则会触发错误回调。 我已经在Safari和FF中测试了GET和POST请求。

一个可能的解决方案是在页面卸载时中止所有AJAX请求,但是在卸载之前调用error handling程序,所以这似乎不可能。

我希望能够通过礼貌警报或modal dialog在客户端优雅地处理诸如500s之类的REAL错误,但我不希望在用户离开页面时调用此处理。

我该怎么做呢?

(也很奇怪:当离开页面时,error handling程序会说textStatus参数是“error”,与接收500 /错误请求时抛出的相同。)

在错误回调或$ .ajax中,您有三个输入参数:

function (XMLHttpRequest, textStatus, errorThrown) { this; // options for this ajax request } 

您可以直接检查xhr.status以获取HTTP响应代码,例如:

 $.ajax({ url: "test.html", cache: false, success: function(html){ $("#results").append(html); }, error: function (xhr, textStatus) { if (xhr.status == 500) { alert('Server error: '+ textStatus); } } }); 

编辑:告诉浏览器断开的连接与服务器关闭的情况(jasonmerino的评论)之间的区别:

在卸载时,xhr.readyState应为0,对于非响应服务器,xhr.readyState应为4。

在所有情况下都要正确处理这个问题。 不幸的是,在许多流行的浏览器中,如果AJAX调用被导航或服务器关闭/无响应取消,则xhr.status是相同的( 0 )。 所以这种技术很少奏效。

这是我积累的一组高度“实用”的黑客,它们在大多数情况下工作得相当好,但仍然不是防弹。 我的想法是尝试捕获导航事件并设置一个在AJAXerror handling程序中检查的标志。 像这样:

 var global_is_navigating = false; $(window).on('beforeunload',function() { // Note: this event doesn't fire in mobile safari global_is_navigating = true; }); $("a").on('click',function() { // Giant hack that can be helpful with mobile safari if( $(this).attr('href') ) { global_is_navigating = true; } }); $(document).ajaxError(function(evt, xhr, settings) { // default AJAX error handler for page if( global_is_navigating ) { // AJAX call cancelled by navigation. Not a real error return; } // process actual AJAX error here. }); 

(我将此作为对主要答案的评论添加,但尚未建立足够的分数来做到这一点!)

我也在FF4和Chrome(9.0.597.107)中看到了这一点。 可能在其他地方,但这对我来说已经够糟糕了!

关于这种情况的一个奇怪的事情是返回的XMLHttpRequest.status === 0

这似乎是检测这种情况的可靠方法,在我的特定情况下,中止显示给用户的自定义error handling:

 error: function (XMLHttpRequest, textStatus, errorThrown) { if (XMLHttpRequest.status === 0) return; // error handling here } 

另外值得一提的是,假设在浏览器返回$ .ajax()调用的JSON解析中可能存在问题,我还尝试更换Douglas Crockford版本的原生JSON.stringify( https: //github.com/douglascrockford/JSON-js )但这并没有什么区别。

错误回调应该获得对XHR对象的引用,检查状态代码以查看它是否是服务器错误?

如果你使用jQuery函数,如$.get$.post$.ajax …那么你可以使用参数text_status来检查失败的类型:

 request = $.get('test.html', function(data){ //whatever }).fail(function(xhr, text_status, error_thrown) { if(text_status!== 'abort'){ console.warn("Error!!"); } }); 

来自jQuery文档 :

jqXHR.fail(function(jqXHR,textStatus,errorThrown){}); 作为错误回调选项的替代构造,.fail()方法替换了不推荐使用的.error()方法。 有关实现的详细信息,请参阅deferred.fail()。