2011-02-03 38 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 
})