2011-02-03 26 views
16

我有一个通用的Ajax错误处理程序编写,像这样:jQuery的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的备份处理机警报“栏”我想提醒“富”而不是:

  error: function(xhr) { 
      if (xhr.status == 404) { 
       //window.location.href = $('#logon').attr('href'); 
       alert("foo");  
      } 
     } 

我sthere反正做到这一点?我不知道如何防止备份开火,因为他们现在似乎都触发了。

回答

8

我不认为你可以用jQuery来控制它。在ajax调用期间发生的任何错误都会调用全局ajaxError。但是,在全局回调之前调用“本地”错误回调,因此您可以设置一个变量,告诉全局回调不运行。

例如:http://jsfiddle.net/e7By8/

+4

确保你只要你做了`如果(handledLocally!)`检查`handledLocally`变量重新设置为false - 另外,你冒着多线程竞争的风险。 – Basic 2011-02-04 10:30:33

+1

我在答案的评论中包含了重置,如果您看到jsfiddle,我将重置handlesLocally变量。是的,这是冒着多线程的风险,但不知道应用程序在做什么,这将工作正常。 – 2011-02-04 20:50:10

3

实际上,我们解决了这个:

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,显示这是如何实现的(一定要单击点击链接之前,在上面运行)有以下几点:

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); 
     } 
    } 
+5

你在这里失去了一个主要的优势 - 它不再是一个默认的错误处理程序,它是一个错误处理程序,你需要记住要附加。如果您遇到一位新的开发人员,并且我不熟悉您的技术,则可能会错过完全的错误处理 – Basic 2011-02-04 10:33:17

1

我加入到由Tim银行的回答这是非常有用的。我只是想改变他使用全局变量并在ajax调用中使用设置的事实。我已经让它默认回落,但这很容易改变。

$('html').ajaxError(function(e, xhr, settings, exception) { 
    if (xhr.status == 404) { 
     alert("html error callback");  
    } 
}); 

$.ajax({ 
    url: "missing.html", 
    global: true 
}); 

我已经编辑我的答案要使用的决定是否传播到全球的事件处理程序

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。阿贾克斯:

doAjax('/someResource'); // defaultErrorHandler using for handle error 
doAjax('/someResource', function() {...}); // custom error function using 
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"); 
}); 
4

我认为设置全局变量是一个坏主意,因为你可以同时有多个Ajax请求。如前所述,在全局回调之前调用“本地”错误回调。我的解决方案只是将一些自定义属性附加到jqXHR对象,例如句柄句柄并将其设置为您的本地处理程序并在全局处理程序中检查它。

局部处理:

$.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 
})