如果我离开$ .ajax()请求中间的页面,则会触发错误回调。我已经在Safari和FF中测试了GET和POST请求。
一个可能的解决方案是在页面卸载时中止所有AJAX请求,但是在卸载之前调用错误处理程序,所以这似乎不可能。
我希望能够在客户端使用礼貌警报或模式对话框优雅地处理诸如500s之类的REAL错误,但我不希望在用户离开页面时调用此处理。 / p>
我该怎么做?
-
(也很奇怪:当离开页面时,错误处理程序会说textStatus参数是“error”,与接收500 /错误请求时抛出的相同。)
答案 0 :(得分:24)
在错误回调或$.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。
答案 1 :(得分:12)
在所有情况下都要正确处理这个问题。不幸的是,在许多流行的浏览器中,如果通过导航或服务器关闭/无响应取消AJAX调用,则xhr.status
是相同的(0
)。所以这种技术很少奏效。
这是我积累的一组高度“实用”的黑客,它们在大多数情况下都能很好地工作,但仍然不是防弹的。我们的想法是尝试捕获导航事件并设置一个在AJAX错误处理程序中检查的标志。像这样:
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.
});
答案 2 :(得分:4)
(我会将此作为对主要答案的评论添加,但还没有积累足够的分数来执行此操作!)
我也在FF4和Chrome(9.0.597.107)中看到了这一点。可能在其他地方,但这对我来说很难解决它!
关于这种情况的一个奇怪的事情是返回的XMLHttpRequest.status === 0
这似乎是检测这种情况的可靠方法,在我的特定情况下,会中止向用户显示的自定义错误处理:
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)但没有区别。
答案 3 :(得分:0)
错误回调应该获得对XHR对象的引用,检查状态代码以查看它是否是服务器错误?
答案 4 :(得分:0)
如果您使用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 docs:
jqXHR.fail(function(jqXHR,textStatus,errorThrown){}); 错误回调选项的替代构造,.fail()方法 替换已弃用的.error()方法。请参阅deferred.fail() 实施细节。
答案 5 :(得分:0)
请稍等片刻,然后显示错误。如果由于页面卸载而导致请求失败,则不会触发超时,并且不会显示错误。我的实验表明,对于桌面Safari和Firefox(台式机和Android)而言100毫秒就足够了,对于iOS Safari而言500毫秒就足够了。持续时间是模糊的,因此,如果可能的话,应增加数字。
const request = new XMLHttpRequest();
// Firefox calls onabort, Safari calls onerror
request.onabort = request.onerror = () => {
// A short comprehensive solution
setTimeout(() => {
alert('The request has failed completely');
}, 500);
// A more gentle solution
const isWebKit = 'ApplePayError' in window;
const isDesktopSafari = !('standalone' in navigator);
const isGecko = 'mozInnerScreenX' in window
setTimeout(
() => {
alert('The request has failed completely');
},
isWebKit ? (isDesktopSafari ? 100 : 500) : (isGecko ? 100 : 0)
);
}
request.open('get', 'http://example.com', true);
request.send();
我仅在现代浏览器(Chrome 87,Firefox 83,IE 11,Edge,Safari 14)中检查了此解决方案。