Czy kod stanu HTTP równy 0 ma jakiekolwiek znaczenie?

91

Wygląda na to, że kiedy wykonujesz XMLHttpRequest ze skryptu w przeglądarce, jeśli przeglądarka jest ustawiona na pracę w trybie offline lub jeśli kabel sieciowy jest wyciągnięty, żądanie kończy się błędem i statusem = 0. 0 nie jest wymienione wśród dozwolonych Kody stanu HTTP.

Co oznacza kod statusu 0? Czy oznacza to to samo we wszystkich przeglądarkach i dla wszystkich narzędzi klienta HTTP? Czy jest to część specyfikacji HTTP, czy też część innej specyfikacji protokołu? Wydaje się, że oznacza to, że w ogóle nie można było wykonać żądania HTTP, być może dlatego, że nie można było znaleźć adresu serwera.

Jaki komunikat o błędzie należy wyświetlić użytkownikowi? „Albo nie masz połączenia z internetem, albo w witrynie występują problemy, albo w adresie może być błąd wpisywania”?

Powinienem dodać do tego, że widzę zachowanie w programie FireFox, gdy jest ustawiony na „Pracuj w trybie offline”, ale nie w programie Microsoft Internet Explorer, gdy jest ustawiony na „Pracuj w trybie offline”. W IE użytkownik otrzymuje okno dialogowe z opcją przejścia do trybu online. FireFox nie powiadamia użytkownika przed zwróceniem błędu.

Proszę o to w odpowiedzi na prośbę o „pokazanie lepszego komunikatu o błędzie”. To, co robi Internet Explorer, jest dobre. Informuje użytkownika, co powoduje problem i daje mu możliwość jego naprawienia. Aby zapewnić równoważny UX z FireFox, muszę wywnioskować przyczynę problemu i poinformować użytkownika. Co w sumie mogę wywnioskować ze Statusu 0? Czy ma znaczenie uniwersalne, czy nic mi nie mówi?

Mark Lutton
źródło
Zobacz to pytanie, które obejmuje ten sam temat: stackoverflow.com/questions/872206/…
Scott Stafford
3
Uważam, że to najdokładniejsza odpowiedź: stackoverflow.com/a/14507670/700206
whitneyland
Kolejny powiązany post - Co oznacza kod stanu HTTP 0
RBT

Odpowiedzi:

155

Krótka odpowiedź

Nie jest to kod odpowiedzi HTTP, ale jest udokumentowany przez WhatWG jako prawidłowa wartość atrybutu statusu odpowiedzi XMLHttpRequestlub odpowiedzi Fetch.

Mówiąc ogólnie, jest to wartość domyślna używana, gdy nie ma prawdziwego kodu stanu HTTP do zgłoszenia i / lub wystąpił błąd podczas wysyłania żądania lub otrzymywania odpowiedzi. Możliwe scenariusze, w których ma to miejsce, obejmują między innymi:

  • Żądanie nie zostało jeszcze wysłane lub zostało przerwane.
  • Przeglądarka nadal czeka na stan odpowiedzi i nagłówki.
  • Połączenie zostało zerwane podczas żądania.
  • Upłynął limit czasu żądania.
  • Żądanie napotkało nieskończoną pętlę przekierowań.
  • Przeglądarka zna stan odpowiedzi, ale nie masz do niej dostępu ze względu na ograniczenia bezpieczeństwa związane z zasadami tego samego pochodzenia .

Długa odpowiedź

Po pierwsze, powtórzenie: 0 nie jest kodem stanu HTTP. Jest ich pełna lista w RFC 7231 sekcja 6.1 , która nie zawiera 0, a wprowadzenie do sekcji 6 jasno stwierdza, że

Element status-code to trzycyfrowy kod całkowity

które 0 nie jest.

.statusUdokumentowano jednak 0 jako wartość atrybutu obiektu XMLHttpRequest, chociaż wyśledzenie wszystkich istotnych szczegółów jest trochę trudne. Zaczynamy od https://xhr.spec.whatwg.org/#the-status-attribute , dokumentując .statusatrybut, który po prostu stwierdza:

statusAtrybut musi zwrócić Response „s statusu .

Może to brzmieć bezmyślnie i tautologicznie, ale w rzeczywistości są tutaj informacje! Pamiętaj, że ta dokumentacja mówi tutaj o .responseatrybucie an XMLHttpRequest, a nie odpowiedzi, więc to mówi nam, że definicja stanu obiektu XHR jest odroczona do definicji statusu odpowiedzi w specyfikacji pobierania.

Ale jaki obiekt odpowiedzi? A jeśli tak naprawdę nie otrzymaliśmy jeszcze odpowiedzi? Wbudowany link w słowie „odpowiedź” prowadzi nas do https://xhr.spec.whatwg.org/#response , który wyjaśnia:

An XMLHttpRequestma powiązaną odpowiedź. O ile nie zaznaczono inaczej, jest to błąd sieci .

Zatem odpowiedź, której stan otrzymujemy, jest domyślnie błędem sieci. Wyszukując wszędzie tam, gdzie w specyfikacji XHR jest używane wyrażenie „set response to” , możemy zobaczyć, że jest ono ustawione w pięciu miejscach:

Patrząc na standard Fetch , widzimy, że:

Błąd sieci to odpowiedź , której stan jest zawsze0

dzięki czemu możemy od razu stwierdzić, że zobaczymy stan 0 w obiekcie XHR w każdym z przypadków, w których specyfikacja XHR mówi, że odpowiedź powinna być ustawiona na błąd sieci. (Co ciekawe, obejmuje to przypadek, w którym strumień ciała jest „błędny”, co zgodnie ze specyfikacją pobierania może się zdarzyć podczas analizowania treści po otrzymaniu statusu - więc teoretycznie przypuszczam, że obiekt XHR może mieć swój status ustawiony na 200, a następnie napotkasz błąd braku pamięci lub coś innego podczas odbierania treści i zmień jego stan z powrotem na 0.)

W standardzie Fetch zauważamy również, że istnieje kilka innych typów odpowiedzi, których status jest zdefiniowany jako 0, których istnienie odnosi się do żądań między źródłami i zasad tego samego pochodzenia:

Nieprzezroczysta przefiltrowana odpowiedź to przefiltrowana odpowiedź, której ... stan to 0...

Odfiltrowana odpowiedź nieprzezroczystego przekierowania to przefiltrowana odpowiedź, której ... stan to 0...

(pominięto różne inne szczegóły dotyczące tych dwóch typów odpowiedzi).

Ale poza tym istnieje również wiele przypadków, w których algorytm pobierania (zamiast specyfikacji XHR, którą już przeglądaliśmy) wzywa przeglądarkę do zwrócenia błędu sieciowego! Rzeczywiście, wyrażenie „zwraca błąd sieci” pojawia się 40 razy w standardzie Fetch. Nie będę próbował tutaj wymieniać wszystkich 40, ale zaznaczam, że są to:

  • Sytuacja, w której schemat żądania jest nierozpoznany (np. Próba wysłania żądania na madeupscheme: //foobar.com)
  • Cudownie niejasna instrukcja „W razie wątpliwości zwróć błąd sieci”. w algorytmach obsługi adresów URL ftp: // i file: //
  • Nieskończone przekierowania: „Jeśli liczba przekierowań żądania wynosi dwadzieścia, zwróć błąd sieci”.
  • Kilka problemów związanych z mechanizmem CORS, takich jak „Jeśli zepsucie odpowiedzi httpRequest nie jest„ cors ”, a zasady zasobów między źródłami sprawdzają, czy zwroty żądań i odpowiedzi są zablokowane, a następnie zwraca błąd sieci”.
  • Błędy połączenia: „Jeśli połączenie nie powiedzie się, zwróć błąd sieci”.

Innymi słowy: gdy coś pójdzie nie tak inne niż uzyskanie prawdziwy kod stanu HTTP error niczym 500 lub 400 z serwera, możesz skończyć z atrybutem stanu 0 na swoim obiekcie użyciem nagłówków XHR lub Fetch obiekt odpowiedzi w przeglądarce. Liczba możliwych przyczyn określonych w specyfikacji jest ogromna.

Na koniec: jeśli z jakiegoś powodu interesuje Cię historia specyfikacji, zwróć uwagę, że ta odpowiedź została całkowicie przepisana w 2020 r. I że możesz być zainteresowany poprzednią wersją tej odpowiedzi , która przeanalizowała zasadniczo te same wnioski z starsza (i znacznie prostsza) specyfikacja W3 dla XHR, zanim zostały one zastąpione przez bardziej nowoczesne i bardziej skomplikowane specyfikacje WhatWG, do których odnosi się ta odpowiedź.

Mark Amery
źródło
53

status 0 pojawia się, gdy wywołanie ajax zostało anulowane przed uzyskaniem odpowiedzi poprzez odświeżenie strony lub zażądanie adresu URL, który jest nieosiągalny.

ten status nie jest udokumentowany, ale istnieje w przypadku wywołań ajax i makeRequest z gadget.io.

mnk
źródło
4
Witaj, czy istnieje sposób na rozróżnienie między żądaniem zakończonym niepowodzeniem („Brak sieci”) i anulowanym?
Ankur,
2
Ten stan jest udokumentowany jako status XmlHttpRequest. Oczywiście nie jest to status http, ale jest udokumentowany. w3.org/TR/XMLHttpRequest/#the-status-attribute Zobacz odpowiedź Marka Amery po więcej szczegółów.
Frédéric
4

Wiem, że to stary post. Ale te problemy nadal istnieją.

Oto kilka moich ustaleń na ten temat, rażąco wyjaśnionych.

„Status” 0 oznacza jedną z 3 rzeczy, zgodnie ze specyfikacją XMLHttpRequest:

  • Rozpoznawanie nazw dns nie powiodło się (na przykład, gdy wtyczka sieciowa jest wyciągnięta)

  • serwer nie odpowiedział (inaczej nieosiągalny lub nieodpowiadający)

  • żądanie zostało przerwane z powodu problemu z CORS (aborcja jest wykonywana przez klienta użytkownika i następuje po niepowodzeniu OPTIONS przed lotem).

Jeśli chcesz pójść dalej, zagłęb się w głąb XMLHttpRequest. Proponuję odczytać sekwencję aktualizacji stanu gotowości ([0,1,2,3,4] to normalna sekwencja, [0,1,4] odpowiada statusowi 0, [0,1,2,4] oznacza brak treści wysłane, co może być błędem lub nie). Możesz także dołączyć słuchaczy do xhr (onreadystatechange, onabort, onerror, ontimeout), aby poznać szczegóły.

Ze specyfikacji (specyfikacja XHR Living ):

const unsigned short UNSENT = 0;
const unsigned short OPENED = 1;
const unsigned short HEADERS_RECEIVED = 2;
const unsigned short LOADING = 3;
const unsigned short DONE = 4;
Obotor
źródło
1
Wszystkie możliwe przyczyny na twojej liście są poprawne, ale lista nie jest wyczerpująca. Na przykład brakuje Ci limitów czasu, nieskończonych pętli przekierowań i innych przyczyn opisanych szczegółowo w mojej odpowiedzi . Jednak wskaźnik do nowej żywej specyfikacji XHR jest przydatny; Powinienem zaktualizować moją odpowiedź, aby zacytować ją zamiast starej specyfikacji W3.
Mark Amery,
0

Od iOS 9 musisz dodać „App Transport Security Settings” do swojego pliku info.plist i zezwolić na „Allow Arbitrary Loads” przed wysłaniem żądania do niezabezpieczonej usługi sieciowej HTTP. Miałem ten problem w jednej z moich aplikacji.

Nirav
źródło
-1

Tak, niektóre jak przerwano wywołanie Ajax. Przyczyna może być następująca.

  1. Przed zakończeniem żądania AJAX, użytkownik przeszedł na inną stronę.
  2. Żądanie Ajax ma limit czasu.
  3. Serwer nie może zwrócić żadnej odpowiedzi.
Vinayak
źródło