2009-03-31 4 views
40

Przepraszam, jeśli jest to coś, co powinienem był w stanie sprawdzić. wszystkie terminy, które chciałem, były przeciążone.obsługuje błąd ajax, gdy użytkownik klika odświeżenie

Oto mój problem: kiedy otwieram stronę, uruchamia ona całą serię wywołań ajaxowych. jeśli wtedy wciśnięto Shift + Refresh, wszystkie te wywołania ajaxowe są uważane za błędy i wyświetlające okna dialogowe z komunikatami o błędach przed ponownym załadowaniem całej strony.

, więc błąd jest wywoływany przez klienta - czy mimo to mogę sprawdzić, czy tak jest, więc mogę go zignorować? np w XMLHttpRequest, lub w funkcji ajax (używam jQuery przy okazji)

+0

wkładacie kod wewnątrz funkcji jQuery onLoad annonymous prawo? Na początku twojego kodu masz: $ (function() {/ * czy wszystkie twoje wywołania ajaxowe tutaj * /}); Powinieneś poczekać, aż Twój DOM zostanie załadowany przed wykonaniem wywołań ajaxowych. – KyleFarris

Odpowiedz

19

[Jest to edycja z poprzedniej odpowiedzi, która miała znakomite pytania, które mam od rozwiązany]

jQuery rzuca zdarzenia błędu kiedy użytkownik odejdzie od strony, odświeżając, klikając łącze lub zmieniając adres URL w przeglądarce. Można wykryć te typy błędów, poprzez wdrożenie programu obsługi błędu dla wywołania AJAX i kontroli obiektu XMLHttpRequest:

$.ajax({ 
    /* ajax options omitted */ 
    error: function (xmlHttpRequest, textStatus, errorThrown) { 
     if(xmlHttpRequest.readyState == 0 || xmlHttpRequest.status == 0) 
       return; // it's not really an error 
     else 
       // Do normal error handling 
}); 
+11

To nie działa tak, jak w reklamie. Kiedy wprowadzam "prawdziwy błąd" przez wyłączenie mojego połączenia sieciowego podczas długiej ankiety, widzę również readyState == 0 i status == 0. –

+6

To nie działa. Ta metoda również zatrzymuje wykrywanie prawdziwych błędów. – Sachindra

+9

Ponowne uruchomienie serwera w środku długiego sondowania również daje 'readyState == 0 && status == 0'. Ta metoda nie jest niezawodna. –

6
var isPageBeingRefreshed = false; 

window.onbeforeunload = function() { 
    isPageBeingRefreshed = true; 
}; 

$.ajax({ 
    error: function (xhr, type, errorThrown) { 
     if (!xhr.getAllResponseHeaders()) { 
      xhr.abort(); 
      if (isPageBeingRefreshed) { 
       return; // not an error 
      } 
     } 
    } 
}); 
+2

Ten * prawie * pracował dla mnie. Pracował w przeglądarkach Firefox, Chrome, IE8, IE10 i w przeglądarce Android. [Ale ** nie ** w Safari iOS] (http://stackoverflow.com/questions/4127621/is-there-any-way-to-use-window-onbeforeunload-on-mobile-safari-for-ios- pomysłowość). Sugestia ulepszenia (która nadal nie działa w Safari/iOS) polegałaby na użyciu '$ (window) .on ('beforeunload', function() {...})' zamiast 'window.beforeunload = function () {...} 'tak, aby nie przejąć/nie przejąć procedury obsługi beforeunload. Ciągle szukam czegoś, co działa również w Safari na iOS. –

2

powyższych technik nie działa na okresowo orzeźwiającym strony (na przykład co pół sekundy). Zorientowałem się, że błąd spowodowany odświeżaniem strony można uniknąć, opóźniając proces obsługi błędów o niewielki czas.

przykład:

$.ajax(...) 
.success(...) 
.error(function(jqXHR) { 
setTimeout(function() { 
    // error showing process 
}, 1000); 
}); 

Poza tą

window.onbeforeunload = funkcja() {// połączeń zatrzymania ajax}

zdarzenia mogą być wykorzystane do rzadziej odświeżanie wywołań ajaxowych.

35

Istnieje kilka jak je podejść do wykrywania tego:

  • Kilka sugerują stosowanie beforeunload obsługi, aby ustawić logiczną flagi tak, że obsługi błędów może wiedzieć, że strona jest rozładowany (Zobacz listę powiązanych/zduplikowanych postów poniżej). To jest świetne, z wyjątkiem tego, że mobile Safari on iOS doesn't support the beforeunload event.

  • Sachindra suggested Podejście polegające na tym, że zamiast natychmiastowo uruchomić funkcję błędu, zostało opóźnione o sekundę w setTimeout(..., 1000). W ten sposób istnieje duża szansa, że ​​strona zniknie w momencie wywołania procedury obsługi błędów. "Dobra szansa". Założę się, jeśli mam ogromną stronę z np. wielu z nich może zająć więcej niż 1 sekundę, aby zwolnić, a następnie prawdopodobnie obsługa błędu i tak by się uruchomiła.

Proponuję zatem kombinację reliably detecting beforeunload support a jeśli beforeunload nie jest obsługiwana (kaszel iPad/iPhone kaszel) powróci do Sachindra zwłoki sztuczki.

Zobacz pełne rozwiązanie z detekcją beforeunload i wszystko w tym jsfiddle.

Wygląda na to, że sytuacja wygląda następująco: a little better for jQuery 2.x than for 1.x, ale 2.x również wydaje się nieco flakey, więc nadal uważam tę sugestię za rozsądną.

P.S: Były również sugestie dotyczące testowania niektórych pól w obiekcie XHR/jqXHR. (Here i here). Nie natknąłem się na kombinację, która mogłaby odróżnić nawigację użytkownika i ponowne uruchomienie serwera podczas długotrwałego wywołania AJAX, dlatego też nie przydał mi się ten sposób.

To jest naprawdę również odpowiedzią na te związane/powielanych pytania przepełnienie stosu:

a te posty poza stos Przelew:

+0

W kwietniu 2017 r. Problem ten występuje tylko w przeglądarce Firefox, która obsługuje wcześniejsze pobieranie. –

2

wersja połączeniu z nisanth074 i Peter V. Mørch odpowiedzi, który pracował dla mnie.

Przykład:

var isPageBeingRefreshed = false; 

$(window).on('beforeunload', function(){ 

    isPageBeingRefreshed = true; 
}); 

$.ajax({ 

    // Standart AJAX settings 

}).error(function(){ 

    if (!isPageBeingRefreshed) { 

     // Displaying error message 
    } 
});