Status XMLHttpRequest 0 (tekst odpowiedzi jest pusty)


104

Nie można pobrać danych za pomocą XMLHttpRequest (status 0 i tekst odpowiedzi jest pusty):

xmlhttp = new XMLHttpRequest ();
xmlhttp.open ("POBIERZ", "http://www.w3schools.com/XML/cd_catalog.xml", prawda);
xmlhttp.onreadystatechange = function () 
{
  if (xmlhttp.readyState == 4)
    alert ("stan" + xmlhttp.status);
}
xmlhttp.send ();

Informuje o „statusie 0”.

Taka sama sytuacja z żądaniem localhost (cd_catalog.xml jest zapisywany jako plik lokalny)

xmlhttp.open ("POBIERZ", "http: //localhost/cd_catalog.xml", true);

Ale z żądaniem adresu IP hosta lokalnego

xmlhttp.open ("POBIERZ", "http://127.0.0.1/cd_catalog.xml", prawda);

i z żądaniem pliku lokalnego

xmlhttp.open ("POBIERZ", "cd_catalog.xml", prawda);

wszystko w porządku (stan 200)

Co może powodować problem (stan = 0) z żądaniem online?

PS: Live HTTP Headers pokazuje, że wszystko jest w porządku we wszystkich 4 przypadkach:

  HTTP / 1.1 200 OK
  Content-Length: 4742

PS2: lokalny serwer WWW Apache na VMWare (system operacyjny hosta Win7, system operacyjny gościa Ubuntu, karta sieciowa - NAT). Przeglądarka - Firefox.


1
Czy Twoja strona testowa http://127.0.0.1jest przypadkiem? ;)
— Roatin Marth


7
Odpowiedziałeś na swoje pytanie. XMLHttpRequestnie może wykonywać żądań między domenami. Istnieją jednak pewne obejścia. Spójrz na przykład na jquery.
— meze

Użyj php, aby pobrać plik. Małe obejście: jquery-howto.blogspot.com/2009/04/…

2
@meze: połączenia międzydomenowe działają z jQuery. Ale jak może nie działać ze zwykłym JavaScriptem, skoro jQuery jest zaimplementowany w JavaScript? Dla mnie to bez sensu. Czy jQuery stosuje jakieś nieprzyjemne obejście?
— Gruber

Odpowiedzi:


55

status wynosi 0, gdy plik html zawierający skrypt jest otwierany w przeglądarce za pomocą schematu pliku. Upewnij się, że umieściłeś pliki na swoim serwerze (apache lub tomcat cokolwiek), a następnie otwórz je za pomocą protokołu http w przeglądarce. (tj. http: //localhost/myfile.html ) To jest rozwiązanie.


1
Dlaczego jest to dyskutowane? To rzeczywiście prawda! Żądania XHR z file: // Adresy URL plików również w file: // Adresy URL faktycznie mają status == 0 po pomyślnym zakończeniu (testowane na FF 24.0.5).
— Daniel Roethlisberger

3
Otrzymuję również status == 0 w przypadku sukcesu w przeglądarce Safari w wersji 6.1.6.
— Planar

Mam status = 0 (ale stan 200 w sieci) przy użyciu obciążenia czasowego add-on na firefox
— JobaDiniz

1
nadal ważna odpowiedź. Odpowiedź HTTP to 200 dla rzeczywistych schematów zdalnych (http i in.) I 0 dla pliku lokalnego ( file://schemat). Oczywiście musisz najpierw zezwolić na ładowanie pliku lokalnego, wyłączając CORS.
— pid

31

Przyczyną twoich problemów jest to, że próbujesz wykonać połączenie międzydomenowe i kończy się niepowodzeniem .

Jeśli zajmujesz się rozwojem hosta lokalnego, możesz wykonywać połączenia między domenami - robię to cały czas.

W przypadku przeglądarki Firefox musisz ją włączyć w ustawieniach konfiguracji

signed.applets.codebase_principal_support = true

Następnie dodaj coś takiego do swojego otwartego kodu XHR:

  if (isLocalHost()){
    if (typeof(netscape) != 'undefined' && typeof(netscape.security) != 'undefined'){
      netscape.security.PrivilegeManager.enablePrivilege('UniversalBrowserRead');
    }
  }

W przypadku IE, o ile dobrze pamiętam, wszystko, co musisz zrobić, to włączyć ustawienia zabezpieczeń przeglądarki w sekcji „Różne → Dostęp do źródeł danych w różnych domenach”, aby umożliwić współpracę z XHR ActiveX.

IE8 i nowsze również dodały możliwości międzydomenowe do natywnych obiektów XmlHttpRequest, ale jeszcze się nimi nie bawiłem.


8
Na wypadek, gdyby ktoś tego potrzebował, dla Chrome musisz uruchomić nową instancję tego (bez żadnej już otwartej) i użyć--allow-file-access-from-files
— TheZ

@TheZ: Czy jesteś w 100%? Słyszałem, że wystarczy uruchomić nową instancję przeglądarki Chrome, z --allow-file-access-from-filesprzełącznikiem, ale nie trzeba zamykać wszystkich innych uruchomionych instancji. Dokładnie tak, jak w przypadku trybu incognito Chrome - możesz z niego korzystać, bez zamykania innych uruchomionych instancji.
— trejder

Wygląda na to, że obsługa „UniversalBrowserRead” została usunięta, więc to obejście nie wchodzi w grę.
— perilandmishap

Może się to również zdarzyć, gdy żądasz strony http ze strony https (jak rozszerzenie w przeglądarce).
— sibvic

Mam problem z tym problemem, mimo że strona html i skrypt AJAX znajdują się w tej samej domenie. Ale co dziwne, wpływa to tylko na niektóre skrypty, w szczególności wszystkie skrypty, które uzyskują dostęp do zasobów MongoDB. Jakieś wskazówki, dlaczego tak się dzieje?
— David Edwards

26

Właściwie upewnij się, że typ przycisku to Przycisk nie wyślij, co spowodowało konflikt statusu w miejscu, w którym ostatnio się spotkałem.


1
Występuje konflikt, ponieważ przesłanie formularza ma pewne domyślne zachowanie, którego musisz zapobiec, jeśli sam obsługujesz zdarzenie i wykonujesz wywołanie Ajax. Można uniemożliwić domyślne zachowanie biorąc wydarzenie w przewodnika i nazywające.preventDefault()
— Jordan

20

Jeśli serwer odpowiada na metodę OPTIONS oraz na GET i POST (niezależnie od tego, którego z nich używasz) z nagłówkiem takim jak:

Access-Control-Allow-Origin: *

To może działać dobrze. Wydaje się w FireFox 3.5 i rekonq 0.4.0. Najwyraźniej z tym nagłówkiem i początkową odpowiedzią na OPCJE serwer mówi do przeglądarki „Śmiało i pozwól, aby to żądanie międzydomenowe przeszło”.


3
To jest właściwa odpowiedź! Więcej informacji znajdziesz na en.wikipedia.org/wiki/Cross-origin_resource_sharing . Jeśli dodasz ten nagłówek, nie będzie to „może zadziałać”, ale „zadziała”. Uwaga: To, co musisz dodać, to HTTP / odpowiedź / nagłówek - możesz to zrobić tylko na serwerze, który kontrolujesz. Nigdy nie będzie możliwe bezpośrednie pobranie pliku w3schools.com/XML/cd_catalog.xml przy użyciu XMLHttpRequest(tj. Zgodnie z pierwotnym pytaniem), ponieważ ten zasób nie zawiera (przynajmniej od 24 kwietnia 2015 r.) Żadnego takiego nagłówka CORS.
— MikeBeaton

13

Weź również pod uwagę limit czasu żądania :

Nowoczesna przeglądarka zwraca readyState = 4 i s tatus = 0, jeśli upłynie zbyt dużo czasu przed odpowiedzią serwera.


3
@AndreaSavojardo: Czy masz jakieś uwagi (takie jak post na MDN) na temat zgodności tego zachowania ze standardami?
— Alexander Abakumov

@AndreaSavojardo Mam readyState = 4 i status = 0, a serwer nie działa, ale szybko pojawia się alert o błędzie… ile czasu upływa, zanim upłynął limit czasu żądania?

7

Dodaj setRequestHeader("Access-Control-Allow-Origin","*")do odpowiedzi serwera.


3

Miałem podobny problem. Wszystko było w porządku, „readystate” wynosił 4, ale „status” wynosił 0. To dlatego, że korzystałem z przenośnego serwera Apache PHP, a mój plik, w którym użyłem obiektu „XMLHttpRequest”, był plikiem html. Zmieniłem rozszerzenie pliku na php i problem został rozwiązany.


3

Otwórz konsolę javascript . Zobaczysz tam komunikat o błędzie. W moim przypadku był to CORS.


2

Aby odpowiedzieć na pytanie, dlaczego http://127.0.0.1/cd_catalog.xmldziała, a http://localhost/cd_catalog.xmlnie: Firefox traktuje 127.0.0.1 i localhost jako dwie różne domeny.


2

Aby zobaczyć, na czym polega problem, gdy pojawi się tajemniczy błąd 0, przejdź do ... | Więcej narzędzi | Narzędzia programistyczne (Ctrl + Shift + I) w Chrome (na stronie podającej błąd)

Przeczytaj czerwony tekst w dzienniku, aby wyświetlić prawdziwy komunikat o błędzie. Jeśli jest tam za dużo, kliknij prawym przyciskiem myszy i Wyczyść konsolę, a następnie powtórz ostatnie żądanie.

Mój pierwszy problem polegał na tym, że po raz pierwszy przekazywałem nagłówki autoryzacji do mojej własnej międzydomenowej usługi internetowej dla przeglądarki.

Miałem już:

Access-Control-Allow-Origin: *

Ale nie:

Access-Control-Allow-Methods: GET, POST, PUT, DELETE
Access-Control-Allow-Headers: Authorization

w nagłówku odpowiedzi mojej usługi internetowej.

Po dodaniu tego, mój błąd zerowy zniknął z mojego własnego serwera WWW, a także podczas lokalnego uruchamiania pliku index.html bez serwera WWW, ale nadal wyświetlał błędy w piórze kodu.

Wróć do ... | Więcej narzędzi | Developer Tools podczas otrzymywania błędu w codepen, i jest to jasno wyjaśnione: codepen używa https, więc nie mogę dzwonić do http, ponieważ bezpieczeństwo jest niższe.

Dlatego muszę hostować moją usługę internetową pod adresem https.

Wiedza o tym, jak uzyskać prawdziwy komunikat o błędzie - bezcenna!


Użyłem tego podejścia (f12 w chrome) i odkryłem, że próbuję przejść z https do http, co po cichu kończyło się niepowodzeniem, nie zapewniając niczego użytecznego. KOMUNIKAT O BŁĘDZIE: VM1152: 1 Zawartość mieszana: Strona pod adresem 'https://mysiteoriginsite' została załadowana przez HTTPS, ale zażądała niezabezpieczonego punktu końcowego XMLHttpRequest 'http://MyDestinationSite/MyService.svc'. To żądanie zostało zablokowane; zawartość musi być dostarczana przez HTTPS.
— GrayDwarf

1

Oto inny przypadek status === 0, specyficzny dla przesyłania:

Jeśli dołączysz 'load'procedurę obsługi zdarzenia XHR.upload, zgodnie z sugestią MDN (przewiń w dół do części „Monitorowanie postępu” przesyłania), obiekt XHR będzie miał, status=0a wszystkie inne właściwości będą pustymi ciągami. Jeśli podłączysz 'load'moduł obsługi bezpośrednio do obiektu XHR, tak jak podczas pobierania treści, wszystko powinno być w porządku (biorąc pod uwagę, że nie korzystasz z lokalnego hosta).

Jeśli jednak chcesz uzyskać dobre dane w swoich 'progress'programach obsługi zdarzeń, musisz dołączyć procedurę obsługi do XHR.upload, a nie bezpośrednio do samego obiektu XHR.

Do tej pory testowałem to tylko na Chrome OSX, więc nie jestem pewien, jak duży problem dotyczy dokumentacji MDN, a ile implementacji Chrome ...


1

Alex Robinson już (i pierwszy) daje poprawną odpowiedź na to pytanie. Ale żeby rozwinąć to trochę bardziej ...

Musisz dodać nagłówek odpowiedzi HTTP:

Access-Control-Allow-Origin: *

Jeśli to zrobisz, rezultatem będzie nie tylko „może zadziałać”, ale „zadziała”.

Uwaga: Musisz dodać nagłówek odpowiedzi HTTP - możesz to zrobić tylko na serwerze, który kontrolujesz. Nigdy nie będzie możliwe bezpośrednie pobranie http://w3schools.com/XML/cd_catalog.xml z oryginalnego adresu URL za pomocą XMLHttpRequest(zgodnie z pytaniem OP), ponieważ ten zasób nie (przynajmniej od 24 kwietnia 2015 r.) zawierać dowolny taki nagłówek CORS.

http://en.wikipedia.org/wiki/Cross-origin_resource_sharing zawiera więcej informacji.


0

Mój problem podobny do tego został rozwiązany poprzez sprawdzenie mojego kodu HTML. Miałem program onclickobsługi w moim formularzu przycisk przesyłania do metody. słuszne: onclick="sendFalconRequestWithHeaders()". Ta metoda z kolei wywołuje Ajax tak jak twoja i robi to, co chcę. Ale nie zgodnie z oczekiwaniami, moja przeglądarka nic nie zwracała.

Nauczyłem się z czyjejś ciężkiej pracy , zwróciłem fałsz w tym programie obsługi i rozwiązałem. Pozwól mi wspomnieć, że przed przybyciem do tego postu, spędziłem cały 3-dniowy weekend i pół dnia w biurze pisania kodu wykonawczego CORS filters, jetty config, inne jersey and embedded jettyrzeczy związane - wystarczy, aby to naprawić, odnawialnego wszystkie moje zrozumienie wokół. cross domain ajax requestsI standardów rzeczy. To było śmieszne, jak proste błędy w javascript sprawiają, że głupi.

Prawdę mówiąc, próbowałem signed.applets.codebase_principal_support = truei pisałem isLocalHost() **if**. może ta metoda musi zostać przez nas zaimplementowana, firefox mówi, że nie ma takiej Teraz muszę wyczyścić kod, aby czysto przesłać łatkę git. Dzięki temu ktoś.


0

Żądanie przeglądarki „127.0.0.1/somefile.html” dociera niezmienione do lokalnego serwera WWW, podczas gdy „localhost / jakiś plik.html” może pojawić się jako „0: 0: 0: 0: 0: 0: 0: 1 / somefile.html” jeśli obsługiwany jest protokół IPv6. Więc to drugie może być przetwarzane jako przejście z jednej domeny do innej.


0

Alex Robinson i bmju dostarczyli cennych informacji, aby zrozumieć problemy związane z różnymi źródłami. Chciałem dodać, że może być konieczne wykonanie jawnego wywołania OPTIONS w kodzie klienta przed wykonaniem żądanego GET / POST (np. Względem punktu końcowego usługi CORS OAuth). Twoja przeglądarka / biblioteka może nie obsługiwać automatycznie żądania OPCJI. Gruber, to jedna z możliwych odpowiedzi na twoje pytanie.


0

Miałem ten sam problem (readyState to 4, a status 0) , potem zastosowałem inne podejście wyjaśnione w tym samouczku: https://spring.io/guides/gs/consuming-rest-jquery/

W ogóle nie używał XMLHttpRequest , zamiast tego użył metody jquery $ .ajax () :

<head>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
    <script src="hello.js"></script>
</head>

<body>
    <div>
        <p class="greeting-id">The ID is </p>
        <p class="greeting-content">The content is </p>
    </div>
</body>

i dla pliku public / hello.js (lub możesz wstawić go bezpośrednio w tym samym kodzie HTML):

$(document).ready(function() 
 {
    $.ajax({
        url: "http://rest-service.guides.spring.io/greeting"
   }).then(function(data) {
      $('.greeting-id').append(data.id);
      $('.greeting-content').append(data.content);
   });
 });

2
Zdajesz sobie sprawę, że jQuery $.ajax()używa XMLHttpRequestod wewnątrz, prawda?
— Manngo


-1

Po prostu miałem ten problem, ponieważ użyłem 0.0.0.0jako mojego serwera, zmieniłem go na localhosti działa.


-4

Edycja: przeczytaj poniższe komentarze Malvolio, ponieważ wiedza w tej odpowiedzi jest nieaktualna.

Nie można wykonywać żądań XMLHttpRequests między domenami.

Wywołanie do 127.0.0.1działa, ponieważ Twoja strona testowa znajduje się pod adresem 127.0.0.1, a test lokalny również działa, ponieważ ... to jest test lokalny.

Pozostałe dwa testy kończą się niepowodzeniem, ponieważ JavaScript nie może komunikować się z odległym serwerem za pośrednictwem XMLHttpRequest.

Zamiast tego możesz rozważyć:

  • XMLHttp - zażądaj własnego serwera, aby pobrać zdalną zawartość XML (na przykład skrypt php)
  • Próbujesz użyć usługi takiej jak GoogleAppEngine, jeśli chcesz zachować pełny JavaScript.

Mam nadzieję, że to pomoże


40
To jest po prostu złe. Państwo może zrobić XMLHttpRequests między domenami.
— Malvolio

1
„Nie możesz”, jak w „Nie powinieneś tego robić, bo to nigdy nie jest dobry pomysł”
— Gabriel Sprenger,

24
- w porządku, ale nie wiem, czy komentarz jest do tego najlepszym forum. Międzydomenowe XMLHttpRequests z pewnością wiążą się z pewnymi wyzwaniami w zakresie bezpieczeństwa, ale oferują wszystkie narzędzia niezbędne do radzenia sobie z tymi wyzwaniami. Poza tym pozwalają stronom internetowym na łatwe oferowanie usług innym stronom internetowym, wykorzystywanie CDN do propagowania danych i szybsze odpowiadanie na żądania użytkowników. Jeśli masz jakieś konkretne pytania, możesz napisać do mnie lub lepiej, zadaj pytanie tutaj na SO i zwróć na nie moją uwagę.
— Malvolio

2
@GabrielSprenger: Cross-domain XMLHttpRequests to nie tylko dobry pomysł, jest tak powszechny w dzisiejszych czasach, że NIE robienie ich w nowoczesnej aplikacji internetowej (poza jakimś rodzajem HelloWorlds) jest czymś śmiesznym. Każda zewnętrzna usługa REST, z której korzysta Twoja aplikacja, wymaga połączenia między domenami XMLHttpRequest. I dlatego wszystkie te rzeczy z CORS zostały dodane.
— Alexander Abakumov
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.