Co to znaczy, że żądanie HTTP zwraca kod stanu 0?

138

Co to znaczy, że wywołania sieciowe JavaScript, takie jak fetch lub XMLHttpRequest, albo inne żądania sieciowe HTTP, kończą się niepowodzeniem z kodem stanu HTTP równym 0?

Wydaje się, że to nie jest prawidłowy kod stanu HTTP, ponieważ inne kody są trzycyfrowe w specyfikacji HTTP.

Próbowałem całkowicie odłączyć sieć w ramach testu. Może to być niepowiązane, ale skutkowało to kodem statusu 17003 (IIRC), którego pobieżne wyszukiwanie sugeruje, że „wyszukiwanie serwera DNS nie powiodło się”.

Ten sam kod działa dobrze w niektórych lokalizacjach i systemach, jednak w niektórych środowiskach kończy się niepowodzeniem z kodem stanu 0 i nie ma dostarczonego tekstu odpowiedzi.

Jest to typowy post HTTP do internetowego adresu URL. Nie obejmuje file: //, co, jak rozumiem, może zwrócić 0, wskazując na sukces w Firefoksie.

mike nelson
źródło
Czy może to być spowodowane zaporą ogniową? W jakim systemie operacyjnym działa Twój klient, na którym działa aplikacja?
shahkalpesh
Może się
przydać
Powiązany post - Co oznacza kod stanu HTTP 0
RBT
Miałem ten sam problem w Firefoksie i dowiedziałem się, że wtyczka blokująca reklamy blokuje wszystkie żądania do adresów URL, które zawierają słowobanner
styczeń

Odpowiedzi:

57

Uważam, że kod błędu wskazuje, że odpowiedź była pusta (ponieważ nie zwrócono nawet nagłówków). Oznacza to, że połączenie zostało zaakceptowane, a następnie prawidłowo zamknięte (TCP FIN). Jest wiele rzeczy, które mogą to powodować, ale z twojego opisu wynika, że ​​jakaś forma zapory ogniowej wydaje się najbardziej prawdopodobnym winowajcą.

Nacięcie
źródło
2
Myślę, że prawdopodobnie masz rację. (Chociaż, jak wskazał @sleepycod wininet.dll, oczekuje się, że zwróci kod statusu w przypadku braku prawdziwego kodu statusu http.)
mike nelson
1
Niekoniecznie jest to poprawne. Miałem ten sam problem, ale w moim przypadku prośba nie została wysłana. Powodem było to, że bloker reklam Firefoksa zapobiegał żądaniom, których adresy URL zawierają słowobanner
styczeń
202

Wiele odpowiedzi jest błędnych. Wygląda na to, że ludzie dowiadują się, co powodowało status == 0 w ich konkretnym przypadku, a następnie uogólniają to jako odpowiedź.

Praktycznie rzecz biorąc, status == 0 dla nieudanego XmlHttpRequest należy uznać za niezdefiniowany błąd.

Rzeczywista specyfikacja W3C definiuje warunki, dla których zwracane jest zero tutaj: https://fetch.spec.whatwg.org/#concept-network-error

Jak widać ze specyfikacji (pobieranie lub XmlHttpRequest) ten kod może być wynikiem błędu, który wystąpił jeszcze przed skontaktowaniem się z serwerem.

Niektóre typowe sytuacje, które powodują powstanie tego kodu stanu, znajdują odzwierciedlenie w innych odpowiedziach, ale może to być dowolny z poniższych problemów lub żaden z nich:

  1. Nielegalne żądanie cross-origin (patrz CORS )
  2. Blokowanie lub filtrowanie zapory
  3. Samo żądanie zostało anulowane w kodzie
  4. Zainstalowane rozszerzenie przeglądarki wszystko psuje

Pomocne byłoby, gdyby przeglądarki udostępniały szczegółowe raporty o błędach dla większej liczby scenariuszy ze stanem == 0. Rzeczywiście, czasami status == 0 będzie towarzyszył pomocnemu komunikatowi konsoli, ale w innych nie ma innych informacji.

Whitneyland
źródło
4
Dodatek do Firefoksa NoScript może anulować żądanie XHR do niezaufanych hostów.
Ivan Solntsev
5
+1, to wszystko jest poprawne, a praktyczną interpretacją jest „wystąpił jakiś błąd”. Dla osób zainteresowanych pełną listą możliwych przyczyn podanych w specyfikacji, opublikowałem zestawienie na stackoverflow.com/a/26451773/1709587 .
Mark Amery,
1
Wśród przypadków opisanych przez Marka Amerykanów, które sprawiają mi najwięcej kłopotów, jest sprawa corsów. Jeśli błąd powoduje odpowiedź na niepowodzenie walidacji cors przy okazji, otrzymasz status 0 zamiast statusu http, ponieważ gdy walidacja cors się nie powiedzie, odpowiedź nie jest dostępna. Szczególnie frustrujące przy próbie wykrycia interfejsu API sieci Web w trakcie konserwacji i odpowiedzi 503. Jeśli ten interfejs API nie honoruje cors podczas konserwacji, nie będziesz w stanie wykryć 503, otrzymasz po prostu 0, co może być spowodowane przez tak wiele innych rzeczy.
Frédéric
Problem z CORS, z którym miałem do czynienia: rozważ użycie httpzamiast tego, httpsczy Twoja strona została początkowo załadowana httpi odwrotnie. Innymi słowy nie wykonuj ajax POSTza pośrednictwem, httpsjeśli twoja strona była dostępna przez httpi nie wykonuj ajax POSTprzez, httpjeśli twoja strona była początkowo dostępna przez https.
Victor Ponamarev
Żądania synchroniczne generują bardziej znaczący wyjątek w przypadku statusu 0: stackoverflow.com/a/49573256/1192811
McX
35

Co jest warte, w zależności od przeglądarki, wywołania AJAX oparte na jQuery wywołają wywołanie zwrotne sukcesu z kodem stanu HTTP 0. Znaleźliśmy kod stanu „0”, który zwykle oznacza, że ​​użytkownik przeszedł wcześniej na inną stronę połączenie AJAX zostało zakończone.

Nie ten sam stos technologii, którego używasz, ale mam nadzieję, że komuś się przyda.

Cory R. King
źródło
Tak, ludzie prawdopodobnie często dostają ten problem, ponieważ ta strona miała 10 000 wyświetleń.
mike nelson
A może powinienem powiedzieć 25 000 wyświetleń?
mike nelson
3
To jest dużo warte: to jest dokładnie to, co mi wypadło w moich automatycznych testach. Wielkie dzięki!
alexfernandez,
Głosowano „za” nie dlatego, że jest to „właściwa” odpowiedź, ale tak właśnie było w moim przypadku.
Juan Mendes,
Zdecydowanie tak się dzieje, ale nie jest to jedyny powód, dla którego zobaczysz kod błędu == 0, nie możesz założyć, że jest to tylko użytkownik odchodzący i dlatego odfiltrowuj komunikaty o błędach tego typu.
wal
14

wininet.dll zwraca zarówno standardowe, jak i niestandardowe kody stanu, które są wymienione poniżej.

401 - Unauthorized file
403 - Forbidden file
404 - File Not Found
500 - some inclusion or functions may missed
200 - Completed

12002 - Server timeout
12029,12030, 12031 - dropped connections (either web server or DB server)
12152 - Connection closed by server.
13030 - StatusText properties are unavailable, and a query attempt throws an exception

Dla kodu stanu „zero”, czy próbujesz wykonać żądanie na lokalnej stronie internetowej działającej na serwerze WWW, czy bez serwera WWW?

XMLHttpRequest status = 0 i XMLHttpRequest statusText = unknown mogą pomóc, jeśli nie uruchamiasz swojego skryptu na serwerze internetowym.

Christophe Eblé
źródło
Dzięki za kody. Nie, nie jest to żądanie lokalne, jest to żądanie do serwera WWW w Internecie z lokalnie działającego vbscript.
mike nelson
7

Kod odpowiedzi HTTP równy 0 oznacza, że ​​żądanie AJAX zostało anulowane.

Może się to zdarzyć z powodu przekroczenia limitu czasu, aborcji XHR lub zapory ogniowej działającej na żądanie. Limit czasu jest powszechny, oznacza to, że żądanie nie zostało wykonane w określonym czasie. Aborcja XHR jest bardzo prosta do wykonania ... faktycznie możesz wywołać .abort () na obiekcie XMLHttpRequest, aby anulować wywołanie AJAX. ( Jest to dobra praktyka dla aplikacji jednostronicowej, jeśli nie chcesz, aby wywołania AJAX powracały i próbowały odwoływać się do obiektów, które zostały zniszczone ) . Jak wspomniano w zaznaczonej odpowiedzi, zapora ogniowa może również anulować żądanie i wywołać to 0 odpowiedzi.

XHR Abort: Przerwij żądania Ajax za pomocą jQuery

var xhr = $.ajax({
    type: "POST",
    url: "some.php",
    data: "name=John&location=Boston",
    success: function(msg){
       alert( "Data Saved: " + msg );
    }
});

//kill the request
xhr.abort()

Warto zauważyć, że uruchomienie metody .abort () na obiekcie XHR również spowoduje wywołanie zwrotnego błędu. Jeśli wykonujesz jakąkolwiek obsługę błędów, która analizuje te obiekty, szybko zauważysz, że przerwane XHR i XHR przekroczenia limitu czasu są identyczne, ale z jQuery textStatus, który jest przekazywany do wywołania zwrotnego błędu, zostanie "przerwany" po przerwaniu i „timeout” z przekroczeniem limitu czasu. Jeśli używasz Zepto (bardzo podobnego do jQuery), ErrorType będzie „error” po przerwaniu i „timeout”, gdy nastąpi przekroczenie limitu czasu.

jQuery: error(jqXHR, textStatus, errorThrown);
Zepto:  error(xhr, errorType, error);
Cory Danielson
źródło
6

Obejście: co ostatecznie zrobiliśmy

Uznaliśmy, że ma to związek z problemami z zaporą, więc wymyśliliśmy obejście, które załatwiło sprawę. Jeśli ktoś ma ten sam problem, oto co zrobiliśmy:

  1. Nadal zapisujemy dane do pliku tekstowego na lokalnym dysku twardym, tak jak poprzednio, używając aplikacji HTA.

  2. Gdy użytkownik kliknie „wyślij dane z powrotem do serwera”, aplikacja HTA wczytuje dane i zapisuje stronę HTML, która zawiera te dane jako wyspę danych XML (w rzeczywistości przy użyciu bloku skryptu SCRIPT LANGUAGE = XML).

  3. Aplikacja HTA uruchamia łącze do strony HTML w przeglądarce.

  4. Strona HTML zawiera teraz javascript, który wysyła dane na serwer (przy użyciu Microsoft.XMLHTTP).

Mam nadzieję, że pomoże to każdemu z podobnymi wymaganiami. W tym przypadku była to gra Flash używana na laptopie na targach. Nigdy nie mieliśmy dostępu do laptopa i mogliśmy tylko wysłać go e-mailem do klienta, ponieważ te targi odbywały się w innym kraju.

mike nelson
źródło
Witam, badam podobny problem, który występuje u klienta w produkcji. Mówisz, że problem spowodowała zapora ogniowa. Czy zdarzyło Ci się pamiętać, jaki był efekt wywołany przez zaporę ogniową lub co zrobiła zapora, aby to spowodować?
Ibrahim Najjar
4

Jak wyszczególniono w tej odpowiedzi na tej stronie , kod stanu równy 0 oznacza, że ​​żądanie nie powiodło się z jakiegoś powodu, a biblioteka javascript zinterpretowała niepowodzenie jako kod stanu równy 0.

Aby to sprawdzić, możesz wykonać jedną z następujących czynności:

1) Użyj tego rozszerzenia przeglądarki Chrome, Requestly, aby przekierować swój adres URL z httpswersji adresu URL do httpwersji, ponieważ spowoduje to błąd bezpieczeństwa zawartości mieszanej i ostatecznie wygeneruje kod stanu równy 0. Zaletą tego podejścia jest to, że nie Nie musisz w ogóle zmieniać swojej aplikacji, możesz po prostu „przepisać” swój adres URL, używając tego rozszerzenia.

2) Zmień kod swojej aplikacji, aby opcjonalnie przekierować punkt końcowy do httpwersji adresu URL zamiast httpswersji (lub odwrotnie). Jeśli to zrobisz, żądanie zakończy się niepowodzeniem z kodem stanu 0.

Brad Parks
źródło
1
„Użyj tego rozszerzenia do Chrome” - rozszerzenie do Chrome? W aplikacji HTA?
Quentin,
4
Na pewno dobra uwaga! Ale większość ludzi przybywających tutaj nie dociera do aplikacji HTA. Szukają w Google „kodu statusu http javascript 0” lub czegoś podobnego i docierają tutaj - więc myślę, że część tego pytania dotycząca HTA ma najmniejsze znaczenie, i ostatecznie jest nadal aktualna.
Brad Parks
2

W moim przypadku stan zmienił się na 0, gdy zapomniałbym umieścić WWW przed moją domeną. Ponieważ wszystkie moje żądania AJAX były zakodowane na stałe pod adresem http: /WWW.moja_domena.com, a załadowana strona internetowa byłaby po prostu http://moja_domena.com , stało się to problemem bezpieczeństwa, ponieważ jest to inna domena. Skończyło się na tym, że przekierowałem w moim pliku .htaccess, aby zawsze umieszczać www na początku.

fellowworldcitizen
źródło
1

W moim przypadku było tak, ponieważ wywołanie AJAX było blokowane przez przeglądarkę z powodu zasady tego samego pochodzenia . To była najmniej oczekiwana rzecz, ponieważ wszystkie moje HTML i skrypty były obsługiwane 127.0.0.1. Jak można uznać, że mają różne pochodzenie?

W każdym razie główną przyczyną był niewinnie wyglądający <base>tag:

<base href='<%=request.getScheme()%>://<%=request.getServerName() + ":" + request.getServerPort() + request.getContextPath()%>/'/>

Usunąłem <base>tag, którego nie potrzebowałem, a teraz działa dobrze!

Saintali
źródło
1

Znalazłem nowy i nieudokumentowany powód statusu == 0. Oto co miałem:

XMLHttpRequest.status === 0
XMLHttpRequest.readyState === 0
XMLHttpRequest.responseText === ''
XMLHttpRequest.state() === 'rejected'

Nie było między źródłami, siecią ani z powodu anulowanych żądań (za pomocą kodu lub nawigacji użytkownika). Nic w konsoli programisty ani w dzienniku sieciowym.

Mogłem znaleźć bardzo mało dokumentacji na temat state () (Mozilla nie podaje jej na liście, W3C robi) i żadna z nich nie wspomniała o odrzuceniu.

Okazuje się, że to mój bloker reklam (uBlock Origin w przeglądarce Firefox).

Jonathan Amend
źródło
1

Oprócz odpowiedzi Lee możesz znaleźć więcej informacji o prawdziwej przyczynie, przełączając się na żądania synchroniczne , ponieważ otrzymasz również wyjątek:

function request(url) {
    var request = new XMLHttpRequest();
    try {
        request.open('GET', url, false);
        request.send(null);
    } catch (e) {
        console.log(url + ': ' + e);
    }
}

Na przykład :

NetworkError: Wystąpił błąd sieci.

McX
źródło
0

Gdyby ktoś inny napotkał ten problem, powodowało to problemy z powodu żądania AJAX i wysyłania normalnego żądania formularza. Rozwiązałem to następującą linią:

<form onsubmit="submitfunc(); return false;">

Kluczem jest powrót false, który powoduje, że formularz nie jest wysyłany. Możesz również po prostu zwrócić false z wnętrza submitfunc (), ale uważam, że napisanie tego jest wyraźniejsze.

samoz
źródło
1
Funkcja Prevent Default działa również w tym przypadku. Jest to funkcja javascript, która zapobiega wykonywaniu przez przeglądarkę domyślnego zachowania podczas zdarzeń, umożliwiając zgrabne nadpisywanie / zapobieganie natywnej funkcjonalności ... return false robi to samo.
Cory Danielson
0

Należy zauważyć, że przesłanie pliku Ajax przekraczające client_max_body_sizedyrektywę dla nginx zwróci ten kod błędu.

r3wt
źródło
0

Jeśli testujesz na lokalnym komputerze, to nie zadziała. Aby przetestować przykład Ajax, musisz umieścić pliki HTML na serwerze WWW.

ExcelinEfendisi
źródło
0

W moim przypadku błąd wystąpił na stronie żądanej za pomocą protokołu HTTP, na której znajduje się skrypt Javascript, który próbuje wykonać żądanie HTTPS. I wzajemnie.

Po załadowaniu strony naciśnij F12 (lub Ctrl + U) i spójrz na kod HTML swojej strony. Jeśli widzisz coś takiego w swoim kodzie:

<!-- javascript request inside the page -->
<script>
var ajaxurl = "https://example.com/wp-admin/admin-ajax.php";
(...)
</script>

Twoja strona została zażądana w ten sposób:

http://example.com/example-page/2019/09/13/my-post/#elf_l1_Lw

Z pewnością napotkasz ten błąd.

Aby to naprawić, ustaw protokół żądania Javascript na taki sam, jak protokół żądania strony.

Ta sytuacja z różnymi protokołami, dla żądań page i js, została wspomniana wcześniej w odpowiedzi Brada Parks, ale wydaje mi się, że przedstawiona tutaj technika diagnostyczna jest łatwiejsza dla większości użytkowników.

aldemarcalazans
źródło