2011-02-03 2 views
16

나는 일반적인 아약스 오류 핸들러과 같이 썼다 : 오류가 403 아니다jQuery를 아약스 일반적인 오류 처리 및 경우에 따라

$('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(); } 
     }); 
    } 

}); 

그래서 때 대화 상자가 텍스트에 관한 함께 표시됩니다 오류.

괜찮지 만 원래 처리기를 백업으로 사용하고 원래의 Ajax 호출에서 개별 오류를 처리해야합니다.

그래서 내가 대신 "foo는"경고하고 싶습니다 (404)의 백업 핸들러 경고 "바"로 :

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

나는이 일을 어쨌든 sthere? 둘 다 순간에 방아쇠를 당기는 것처럼 백업이 실행되는 것을 방지하는 방법을 모르겠습니다.

답변

8

jQuery로 제어 할 수 없다고 생각합니다. 전역 ajaxError는 ajax 호출 중에 발생하는 모든 오류에서 호출됩니다. 그러나 글로벌 콜백이 실행되지 않도록 지시하는 변수를 설정할 수 있도록 전역 콜백보다 먼저 "로컬"오류 콜백이 호출됩니다. 예를 들어

: 우리는 실제로이 문제를 해결 http://jsfiddle.net/e7By8/

+4

당신이 바로이'(! handledLocally)의 경우'체크를 한 적이으로 false로'handledLocally' 변수를 재설정해야합니다 또한 멀티 스레딩 경쟁 조건의 위험에 처해 있습니다. – Basic

+1

답변의 주석에 리셋을 포함 시켰습니다. jsfiddle을 보면 handlesLocally 변수가 재설정되었습니다. 예, 이것은 다중 스레드 조건의 위험을 감수하고 있지만 응용 프로그램이 무엇을하는지 모르는 상태에서 정상적으로 작동합니다. –

3

: 당신이 수행 할 수있는 방법을 보여줍니다이 jsFiddle을 볼 수 있습니다

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; 
} 

이 (확인은 링크를 클릭하기 전에 상단에있는 실행을 클릭합니다)

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 호출이 이제 두 가지 방법 중 하나를 사용하여 funciton를 참조합니다 :

다음과 우리가 원하는 경우 기본이 발생하는

1)이이

error: function(xhr) { 

     if (xhr.status == 404) { 
      alert("local"); 
     } 
     else { 
      // revert to default 
      ajaxError.apply(this, arguments); 
     } 
    } 
+5

여기에서 하나의 큰 장점을 잃고 있습니다. 더 이상 기본 오류 처리기가 아니며, 첨부해야한다는 오류 처리기입니다. 당신의 기술에 익숙하지 않은 새로운 개발자가 생기면 오류 처리가 완전히 누락 될 수 있습니다. – Basic

+0

동의하지만, 반복하지 않고 기본값이 아닌 인스턴스를 처리하는 방법을 알아낼 수 없었습니다. – RyanP13

+1

내가 호기심에서 벗어난 이유는 무엇인가? –

19

설정할 수있는 기본을 진행 한 후 적발되지 않은 경우 우리는 특정 상황을 대상으로 할 경우

error: ajaxError 

2) ajax 속성에서 "global"을 false로 처리하면 자체 오류 처리가 수행됩니다. 그것은 전역 오류 처리를 방지해야합니다. 확인 : http://api.jquery.com/jQuery.ajax#toptions.

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

나는 글로벌 이벤트 핸들러

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이 더 유용하다는 것을 알았지 만 전역 변수를 사용하는 것은 좋지 않습니다. 또한 한 번에 하나 이상의 아약스 호출을 할 수도 있고 작동하지 않을 수도 있습니다. 어떤 아약스를 호출 할 때 오류 스스로 처리 할 수있는 다음

$(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({ 
    url: "/somePage/", 
    handErrorLocally: true 
}).done(function() { 
    alert("good"); 
}).fail(function() { 
    alert("fail"); 
}); 

또는 글로벌 핸들러가 관리 보자 :

$.ajax({ 
    url: "/somePage/" 
}).done(function() { 
    alert("good"); 
}); 
4

I을 나는 약간 다른이 대안을 제안한다 여러 개의 Ajax 요청을 동시에 가질 수 있기 때문에 set 글로벌 변수가 좋지 않다고 생각한다. "로컬"오류 콜백은 전역 콜백보다 먼저 호출됩니다. 내 솔루션 그냥 jqXHR 개체에 handlesLocally 같은 일부 사용자 지정 속성을 첨부하고 로컬 처리기에서 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 
}) 
+0

이 답변이 가장 좋습니다. –