我有一个通用的ajax错误处理程序,如下所示:
$('html').ajaxError(function(e, xhr, settings, exception) {
var message = '';
if (xhr.status == 0) {
message = 'You are offline!\n Please check your network.';
}
else if (xhr.status == 403) {
window.location.href = $('#logon').attr('href');
}
else if (xhr.status == 404) {
message = 'Requested URL not found.';
}
else if (xhr.status == 500) {
message = xhr.responseText;
$('#cboxLoadedContent div.news_article_content').append('<p>' + message + '</p>');
try {//Error handling for POST calls
message = JSON.parse(xhr.responseText);
}
catch (ex) {//Error handling for GET calls
message = xhr.responseText;
}
}
else if (errStatus == 'parsererror') {
message = 'Error.\nParsing JSON Request failed.';
}
else if (errStatus == 'timeout') {
message = 'Request timed out.\nPlease try later';
}
else {
message = ('Unknown Error.\n' + xhr.responseText);
}
if (message != '' && xhr.status != 500) {
message = message;
}
if (xhr.status != 403) {
$('#icis_dashboard').append('<p id="ajax_error_msg" class="offScreen">' + message + '</p>');
errorBox({
inline: true,
width: 0,
href: '#ajax_error_msg',
onLoadCall: function() { $('#cboxLoadedContent').jScrollPaneRemove(); },
onCleanupCall: function() { $('#ajax_error_msg').remove(); }
});
}
});
因此,当错误不是403时,会显示一个对话框,其中包含与错误相关的文本。
这很好,但我想做的是将通用处理程序作为备份,然后在原始ajax调用中单独处理每个错误。
因为备份处理程序警告404上的“bar”我想警告“foo”:
error: function(xhr) {
if (xhr.status == 404) {
//window.location.href = $('#logon').attr('href');
alert("foo");
}
}
无论如何我都坚持这样做?我不知道如何防止备份被触发,因为它们现在似乎都在触发。
答案 0 :(得分:20)
您可以在执行自己的错误处理的ajax函数中将ajax属性“global”设置为false。这应该可以防止全局错误处理。检查:http://api.jquery.com/jQuery.ajax#toptions。
答案 1 :(得分:8)
我认为你不能用jQuery来控制它。在ajax调用期间发生的任何错误都会调用全局ajaxError。但是,在全局回调之前调用“本地”错误回调,因此您可以设置一个变量来告诉全局回调不要运行。
例如:
var handledLocally = false;
$('html').ajaxError(function(e, xhr, settings, exception) {
if (!handledLocally){
//run the normal error callback code and the reset handledLocally
}
});
error: function(){
//set handledLocally to true to let the global callback it has been taken care of
handledLocally = true;
}
您可以查看此jsFiddle,其中显示了如何完成此操作(请务必在点击链接之前单击顶部的运行):http://jsfiddle.net/e7By8/
答案 2 :(得分:4)
我认为设置全局变量是个坏主意,因为你可以同时拥有多个ajax请求。如上所述&#34;本地&#34;在全局回调之前调用错误回调。我的解决方案只是将一些自定义属性附加到jqXHR对象,例如 processedLocally ,并在本地处理程序中将其设置为true并在全局处理程序中检查它。
本地处理:
$.ajax({
//some settings
error:function(jqXHR, textStatus, errorThrown){
//handle and after set
jqXHR.handledLocally = true
}
})
全球处理:
$(document).ajaxError(function (event, jqXHR, ajaxSettings, thrownError) {
if (jqXHR.handledLocally)) {
return;
}
//handle global error
})
答案 3 :(得分:3)
我们实际上通过以下方式解决了这个问题:
function ajaxError(xhr, textStatus, errorThrown) {
var message = '';
if (xhr.status == 0) {
message = 'You are offline!\n Please check your network.';
}
else if (xhr.status == 403) {
window.location.href = $('#logon').attr('href');
}
else if (xhr.status == 404) {
message = 'Requested URL not found.';
}
else if (xhr.status == 500) {
message = xhr.responseText;
$('#cboxLoadedContent div.news_article_content').append('<p>' + message + '</p>');
try {//Error handling for POST calls
message = JSON.parse(xhr.responseText);
}
catch (ex) {//Error handling for GET calls
message = xhr.responseText;
}
}
else if (errStatus == 'parsererror') {
message = 'Error.\nParsing JSON Request failed.';
}
else if (errStatus == 'timeout') {
message = 'Request timed out.\nPlease try later';
}
else {
message = ('Unknown Error.\n' + xhr.responseText);
}
if (message != '' && xhr.status != 500) {
message = message;
}
if (xhr.status != 403) {
$('#icis_dashboard').append('<p id="ajax_error_msg" class="offScreen">' + message + '</p>');
errorBox({
inline: true,
width: 0,
href: '#ajax_error_msg',
onLoadCall: function() { $('#cboxLoadedContent').jScrollPaneRemove(); },
onCleanupCall: function() { $('#ajax_error_msg').remove(); }
});
}
};
因此,现在每个AJAX调用都会以两种方式之一引用该函数:
1)如果我们想要默认发生
error: ajaxError
2)如果我们想要针对特定情况,如果没有捕获,则继续使用默认
error: function(xhr) {
if (xhr.status == 404) {
alert("local");
}
else {
// revert to default
ajaxError.apply(this, arguments);
}
}
答案 4 :(得分:3)
这是一个老问题,但这可能对某人有用。 this answer的问题在于您可能需要执行全局处理程序中的代码。我发现this other answer更有用,但使用全局变量并不是一个很好的做法。此外,您可能同时有多个ajax调用,但它无法正常工作。我建议这个替代方案略有不同:
$(document).ajaxError(function(event, jqxhr, settings, thrownError) {
// Global validation like this one:
if (jqxhr.status == 401) { window.location = "/login"; }
if (!settings.handErrorLocally) {
// Unhandled error.
alert("Ooops... we have no idea what just happened");
}
});
然后在调用任何ajax时你可能会自己处理错误:
$.ajax({
url: "/somePage/",
handErrorLocally: true
}).done(function () {
alert("good");
}).fail(function () {
alert("fail");
});
或者让全球经纪人照顾:
$.ajax({
url: "/somePage/"
}).done(function () {
alert("good");
});
答案 5 :(得分:2)
将全局错误处理程序定义为函数
function ajaxError() {
var message = '';
if (xhr.status == 0) {
message = 'You are offline!\n Please check your network.';
}
.....
}
创建jQuery.ajax包装器:
function doAjax(url, fnError) {
jQuery.ajax(url, {
error: fnError || defaultErrorHandler
})
}
现在使用这个包装器而不是默认的jQuery.ajax:
doAjax('/someResource'); // defaultErrorHandler using for handle error
doAjax('/someResource', function() {...}); // custom error function using
答案 6 :(得分:1)
我正在补充Tim Banks的答案,这非常有用。我只想改变他使用全局变量并在ajax调用中使用设置的事实。我已经默认退回了,但这很容易改变。
$('html').ajaxError(function(e, xhr, settings, exception) {
if (xhr.status == 404) {
alert("html error callback");
}
});
$.ajax({
url: "missing.html",
global: true
});
我编辑了我的答案,使用全局设置决定是否传播到全局事件处理程序