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()。