2011-01-26 11 views
68

Chcę mieć globalną metodę obsługi błędów dla połączeń Ajax, to jest to, co mam teraz:błąd Jquery Ajax obsługi ignorować przerwana

$.ajaxSetup({ 
    error: function (XMLHttpRequest, textStatus, errorThrown) { 
    displayError(); 
    } 
}); 

muszę zignorować błąd aborted. errorThrown ma wartość null, a textStatus jest error. Jak sprawdzić dla aborted?

+3

Dla mnie textStatus jest "przerwać". Widzę, że to stare pytanie - może się zmieniło. – jackocnr

+0

Dla mnie nadal jest to "błąd". –

Odpowiedz

46

miałem do czynienia dzisiaj z samego przypadku użycia. Aplikacja, nad którą pracuję, ma te długo działające wywołania ajax, które mogą być przerywane przez 1) nawigację użytkownika lub 2) tymczasową awarię połączenia/serwera. Chcę, aby procedura obsługi błędów działała tylko w przypadku błędu połączenia/serwera, a nie w przypadku nawigacji użytkownika.

Najpierw wypróbowałem odpowiedź Alastaira Pittsa, ale nie zadziałało, ponieważ zarówno przerwane żądania, jak i niepowodzenie połączenia ustawiły kod statusu i readyState na 0. Następnie próbowałem odpowiedzi sieppl; również nie działał, ponieważ w obu przypadkach nie podano odpowiedzi, a więc nie ma nagłówka.

Jedynym rozwiązaniem, które zadziałało, jest ustawienie detektora dla window.onbeforeunload, który ustawia zmienną globalną wskazującą, że strona została wyładowana. Procedura obsługi błędów może następnie sprawdzić i wywołać procedurę obsługi błędów tylko wtedy, gdy strona nie została rozładowana.

var globalVars = {unloaded:false}; 
$(window).bind('beforeunload', function(){ 
    globalVars.unloaded = true; 
}); 
... 
$.ajax({ 
    error: function(jqXHR,status,error){ 
     if (globalVars.unloaded) 
      return; 
    } 
}); 
+3

To nie działa, jeśli żądanie ajax zostanie przerwane przez JavaScript –

+1

To nie jest poprawna odpowiedź. W beforeunload rozładunek można anulować. Jeśli tak się stanie, wszystkie kolejne błędy Ajax zostaną zignorowane. – LOST

+0

@LOST Procedura obsługi 'beforeunload' jest zdefiniowana przez użytkownika. Dlaczego ustawiłeś wartość globalVars.unloaded na "true", jeśli zamierzasz anulować rozładowywanie w ten sam sposób? – bluecollarcoder

21

Coś, co znalazłem, to fakt, że w przypadku przerwanego żądania status i/lub readyState są równe 0.

W moim globalnej obsługi błędów, mam czek na górze metody:

$(document).ajaxError(function (e, jqXHR, ajaxSettings, thrownError) { 
    //If either of these are true, then it's not a true error and we don't care 
    if (jqXHR.status === 0 || jqXHR.readyState === 0) { 
     return; 
    } 

    //Do Stuff Here 
}); 

Znalazłem ten działa idealnie dla mnie. Mam nadzieję, że to pomoże, lub ktokolwiek inny, kto się w to zagłębi :)

+1

Otrzymuję ten sam status i readyState, jeśli ajax nie może połączyć się z serwerem, aby rozpocząć. Ale jest to błąd, który chcę obsłużyć. Tylko nie przerwał. – Mitar

2
$(document).ajaxError(function(event, jqXHR, ajaxSettings, thrownError) { 

    if (!jqXHR.getAllResponseHeaders()) { 
     return; 
    }   
}); 
+1

Nie pomaga też. W przypadku przerwanych żądań i błędów połączenia z serwerem nagłówki odpowiedzi są puste. –

+0

@ClovisSix Tak, powyższe rozwiązanie sprawdza, czy nagłówek odpowiedzi jest pusty i czy irytuje komunikaty o błędach. Działa dobrze na wielu komercyjnych systemach, które uruchamiamy. Czy możesz podać więcej szczegółów, co próbujesz osiągnąć/twój problem? – sieppl

+0

Wyświetlamy wiadomości, jeśli żadne z naszych żądań nie może połączyć się z serwerem. Nie pokazujemy ich przy ręcznym przerywaniu, ale największym problemem było przejście użytkownika na następną stronę, która powodowała błędy połączenia i nie było sposobu na rozróżnienie między przerwanym żądaniem a błędem połączenia. Rozwiązałem problem, ustawiając var na window.onbeforeunload. Co prawie wykrywa ręczne przerwanie. –

10

Będziesz chciał spojrzeć na argument textStatus przekazany do funkcji błędu. Według http://api.jquery.com/jQuery.ajax/ może przyjmować wartości "sukces", "niezmodyfikowany", "błąd", "limit czasu", "przerwać" lub "parsererror". "Przerwij" jest oczywiście tym, co chcesz sprawdzić.

Dłuższe nuty tutaj: jquery-gotcha-error-callback-triggered-on-xhr-abort

+0

Myślę, że graliśmy z tym i nie udało nam się wykryć rodzaju wiadomości o błędach, które mieliśmy. – sieppl

2

Opierając Alastair Pitts'a answer, można również zrobić to mieć więcej komunikatów informacyjnych:

$(document).ajaxError(function (e, jqXHR, ajaxSettings, thrownError) 
{ 
    { 
     if (jqXHR.status === 0) 
     { 
      alert('Not connect.\n Verify Network.'); 
     } else if (jqXHR.status == 404) 
     { 
      alert('Requested page not found. [404]'); 
     } else if (jqXHR.status == 500) 
     { 
      alert('Internal Server Error [500].'); 
     } else if (exception === 'parsererror') 
     { 
      alert('Requested JSON parse failed.'); 
     } else if (exception === 'timeout') 
     { 
      alert('Time out error.'); 
     } else if (exception === 'abort') 
     { 
      alert('Ajax request aborted.'); 
     } else 
     { 
      alert('Uncaught Error.\n' + jqXHR.responseText); 
     } 
    } 
}); 
0

miałem ten sam problem tutaj, a to, co zrobiłem jako rozwiązanie było ustawić „Przerwanie” var tuż przed wywołaniem Abort(), jak poniżej:

aborting = true; 
myAjax.abort(); 

i tylko pokazać błąd na błędzie obsługi żądania ajax, jeżeli przerwanie nie jest prawdą.

$.ajax({ 
    [..] 
    error: function() { 
     if (!aborting) { 
      // do some stuff.. 
     } 
     aborting = false; 
    } 
}); 
3

Ponieważ bluecollarcoders odpowiedź nie działa dla żądań ajax przerwane przez javascript, tu jest moje rozwiązanie:

var unloaded = false; 
... 
$(window).bind('beforeunload', function(){ 
    unloaded = true; 
}); 


$(document).ajaxError(function(event, request, settings) { 
    if (unloaded || request.statusText == "abort") { 
     return; 
    } 
    ... 
} 

np

handler = jQuery.get("foo") 
handler.abort() 

zostanie zignorowany przez ajaxError obsługi

32

W nowoczesnych jQuery można po prostu sprawdzić, czy request.statusText jest równa 'abort':

error: function (request, textStatus, errorThrown) { 
    if (request.statusText =='abort') { 
     return; 
    } 
} 
+0

uzyskać tekst "błąd" – evtuhovdo

+2

w chrome, mogę sprawdzić dla "abort". w firefox dostaję "błąd". Rozwiązanie z @bluecollarcoder wydaje się dla nas najlepsze. – foxontherock

0
var ProductSearchTouchAjax = null; 
function GetItemsTouchAjax(SearchString) { 

    if (ProductSearchTouchAjax != null) { 
     ProductSearchTouchAjax.abort(); 
    } 
    ProductSearchTouchAjax = $.ajax("../Sale/ProductSearchTouchAjax?SearchString=" + SearchString) 
        .done(function (data) { 

        }) 
        .fail(function (request, textStatus, errorThrown) { 
         debugger; 
         if (textStatus == "abort") { 
          return; 
         } else { 
          alert("error-GetProductInfo"); 
         } 
        }); 
} 
Powiązane problemy