XMLHttpRequest stato 0 (responseText è vuoto)


104

Impossibile ottenere dati con XMLHttpRequest (lo stato 0 e responseText è vuoto):

xmlhttp = nuovo XMLHttpRequest ();
xmlhttp.open ("GET", "http://www.w3schools.com/XML/cd_catalog.xml", true);
xmlhttp.onreadystatechange = funzione () 
{
  if (xmlhttp.readyState == 4)
    alert ("status" + xmlhttp.status);
}
xmlhttp.send ();

Avvisa lo "stato 0".

La stessa situazione con la richiesta localhost (cd_catalog.xml viene salvato come file locale)

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

Ma con la richiesta IP localhost

xmlhttp.open ("GET", "http://127.0.0.1/cd_catalog.xml", true);

e con la richiesta del file locale

xmlhttp.open ("GET", "cd_catalog.xml", true);

tutto è OK (stato 200)

Cosa può causare il problema (stato = 0) con la richiesta online?

PS: Live HTTP Headers mostra che tutto è OK in tutti e 4 i casi:

  HTTP / 1.1 200 OK
  Lunghezza contenuto: 4742

PS2: server Web locale Apache su VMWare (sistema operativo host Win7, sistema operativo guest Ubuntu, adattatore di rete - NAT). Browser: Firefox.


1
La tua pagina di test è http://127.0.0.1per caso? ;)
Roatin Marth

Sì. <code> 127.0.0.1/CDCatalogTest.html </code>
arigasa

7
Hai risposto alla tua domanda. XMLHttpRequestnon può fare richieste interdominio. Ci sono però alcune soluzioni alternative. Guarda jquery, per esempio.
meze

Usa php per ottenere il file. Piccola soluzione: jquery-howto.blogspot.com/2009/04/…

2
@meze: le chiamate interdominio funzionano con jQuery. Ma come può non funzionare con JavaScript normale, poiché jQuery è implementato in JavaScript? Non ha senso per me. JQuery sta usando una sorta di brutta soluzione alternativa?
Gruber

Risposte:


55

status è 0 quando il tuo file html contenente lo script viene aperto nel browser tramite lo schema file. Assicurati di posizionare i file nel tuo server (apache o tomcat qualunque) e poi aprilo tramite protocollo http nel browser. (es. http: //localhost/myfile.html ) Questa è la soluzione.


1
Perché questo è stato downvoted? È proprio vero! Richieste XHR da file: // URL di file anche su file: // gli URL hanno effettivamente lo stato == 0 in caso di successo (testato su FF 24.0.5).
Daniel Roethlisberger

3
Ricevo anche lo stato == 0 in caso di successo su Safari versione 6.1.6.
Planare

Ho lo stato = 0 (ma lo stato 200 sulla rete) utilizzando Carica componente aggiuntivo temporaneo su Firefox
JobaDiniz

1
risposta ancora valida. La risposta HTTP è 200 per gli schemi remoti effettivi (http et al.) E 0 per il file locale ( file://schema). Ovviamente, devi prima consentire il caricamento del file locale disabilitando CORS.
pid

31

La causa dei tuoi problemi è che stai tentando di eseguire una chiamata interdominio e non riesce .

Se stai sviluppando localhost, puoi effettuare chiamate interdominio: lo faccio sempre.

Per Firefox, devi abilitarlo nelle impostazioni di configurazione

signed.applets.codebase_principal_support = true

Quindi aggiungi qualcosa di simile al tuo codice aperto XHR:

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

Per IE, se ricordo bene, tutto ciò che devi fare è abilitare le impostazioni di sicurezza del browser in "Varie → Accedi alle origini dati tra domini" per farlo funzionare con gli ActiveX XHR.

IE8 e versioni successive hanno anche aggiunto funzionalità interdominio agli oggetti XmlHttpRequest nativi, ma non ho ancora giocato con quelli.


8
Nel caso in cui qualcuno ne abbia bisogno, per Chrome è necessario avviare una nuova istanza (senza alcuna già aperta) e utilizzare--allow-file-access-from-files
TheZ

@TheZ: Sei al 100%? Ho sentito che devi solo eseguire una nuova istanza di Chrome, con --allow-file-access-from-filesswitch, ma non devi chiudere tutte le altre istanze in esecuzione. Esattamente come nel caso della modalità di navigazione in incognito di Chrome : puoi utilizzarla senza chiudere altre istanze in esecuzione.
trejder

Sembra che il supporto per "UniversalBrowserRead" sia stato abbandonato, quindi questa soluzione non è un'opzione.
perilandmishap

Inoltre, potrebbe accadere quando richiedi la pagina http dalla pagina https (come l'estensione nel browser).
sibvic

Sto riscontrando questo problema, nonostante la pagina html e lo script AJAX risiedano nello stesso dominio. Ma stranamente, influisce solo su alcuni script, in particolare su qualsiasi script che accede alle risorse MongoDB. Qualche indizio sul perché questo sia?
David Edwards

26

In realtà assicurati che il tuo tipo di pulsante sia Button not Submit, che ha causato un conflitto di stato dove mi sono incontrato di recente.


1
C'è un conflitto perché l'invio di un modulo ha un comportamento predefinito che devi impedire se gestisci l'evento e fai una chiamata ajax da solo. Puoi impedire il comportamento predefinito prendendo l'evento nel tuo gestore e chiamandoe.preventDefault()
Jordan

20

Se il server risponde a un metodo OPTIONS e a GET e POST (a seconda di quale di essi stai utilizzando) con un'intestazione come:

Access-Control-Allow-Origin: *

Potrebbe funzionare bene. Sembra in FireFox 3.5 e rekonq 0.4.0. Apparentemente, con quell'intestazione e la risposta iniziale a OPTIONS, il server sta dicendo al browser: "Vai avanti e lascia che questa richiesta interdominio vada a buon fine".


3
Questa è la risposta esatta! Guarda en.wikipedia.org/wiki/Cross-origin_resource_sharing per maggiori informazioni. Se aggiungi questa intestazione, non è "potrebbe funzionare", ma "funzionerà". NB Quello che devi aggiungere è un HTTP / response / header, quindi puoi farlo solo su un server che controlli. Non sarà mai possibile recuperare direttamente w3schools.com/XML/cd_catalog.xml utilizzando XMLHttpRequest(cioè come da domanda originale), perché quella risorsa non include (almeno al 24 aprile 2015) alcuna intestazione CORS di questo tipo.
MikeBeaton

13

Considera anche il timeout della richiesta :

Il browser moderno restituisce readyState = 4 e s tatus = 0 se passa troppo tempo prima della risposta del server.


3
@AndreaSavojardo: hai qualche riferimento (come un post su MDN) sul fatto che questo comportamento sia conforme agli standard?
Alexander Abakumov

@AndreaSavojardo ho readyState = 4 e status = 0 e il server non è in esecuzione ma l'avviso di errore mi viene mostrato velocemente .... quanto tempo passa per "request time out"?

7

Aggiungi setRequestHeader("Access-Control-Allow-Origin","*")alla risposta del tuo server.


3

Avevo affrontato un problema simile. Tutto andava bene, "readystate" era 4, ma lo "status" era 0. Era perché stavo usando un server portatile Apache PHP e il mio file in cui ho usato l'oggetto "XMLHttpRequest" era un file html. Ho cambiato l'estensione del file in php e il problema è stato risolto.


3

Apri la console javascript . Vedrai un messaggio di errore lì. Nel mio caso è stato CORS.


2

Per rispondere alla domanda sul perché http://127.0.0.1/cd_catalog.xmlfunziona mentre http://localhost/cd_catalog.xmlnon funziona: Firefox tratta 127.0.0.1 e localhost come due domini diversi.


2

Per vedere qual è il problema, quando ottieni l'errore criptico 0 vai a ... | Altri strumenti | Strumenti per sviluppatori (Ctrl + Maiusc + I) in Chrome (nella pagina che dà l'errore)

Leggere il testo in rosso nel registro per ottenere il vero messaggio di errore. Se c'è troppo dentro, fai clic con il pulsante destro del mouse e Cancella console, quindi fai di nuovo l'ultima richiesta.

Il mio primo problema è stato che stavo passando per la prima volta le intestazioni di autorizzazione al mio servizio Web interdominio per il browser.

Avevo già:

Access-Control-Allow-Origin: *

Ma no:

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

nell'intestazione della risposta del mio servizio web.

Dopo averlo aggiunto, il mio errore zero era sparito dal mio server web, così come durante l'esecuzione del file index.html localmente senza un server web, ma dava ancora errori nella penna del codice.

Torna a ... | Altri strumenti | Strumenti per sviluppatori durante la visualizzazione dell'errore in codepen, e viene spiegato chiaramente: codepen utilizza https, quindi non posso effettuare chiamate a http, poiché la sicurezza è inferiore.

Devo quindi ospitare il mio servizio web su https.

Sapere come ottenere il vero messaggio di errore - impagabile!


Ho usato questo approccio (f12 in chrome) e ho scoperto che stavo cercando di passare da https a http che non funzionava silenziosamente senza fornire nulla di utile. MESSAGGIO DI ERRORE: VM1152: 1 Contenuto misto: la pagina all'indirizzo è 'https://mysiteoriginsite' stata caricata su HTTPS, ma ha richiesto un endpoint XMLHttpRequest non sicuro 'http://MyDestinationSite/MyService.svc'. Questa richiesta è stata bloccata; il contenuto deve essere offerto tramite HTTPS.
GrayDwarf

1

Ecco un altro caso in cui status === 0, specifico per il caricamento:

Se colleghi un 'load'gestore di eventi a XHR.upload, come suggerito da MDN (scorri verso il basso fino alla parte di caricamento di "Monitoraggio avanzamento"), l'oggetto XHR avrà status=0e tutte le altre proprietà saranno stringhe vuote. Se 'load'colleghi il gestore direttamente all'oggetto XHR, come faresti quando scarichi il contenuto, dovresti stare bene (dato che non stai scappando da localhost).

Tuttavia, se si desidera ottenere dati validi nei 'progress'gestori di eventi, è necessario collegare un gestore a XHR.upload, non direttamente all'oggetto XHR stesso.

Finora l'ho testato solo su Chrome OSX, quindi non sono sicuro di quanto il problema qui sia la documentazione di MDN e quanto sia l'implementazione di Chrome ...


1

Alex Robinson già (e primo) dà la risposta corretta a questo problema. Ma per elaborarlo un po 'di più ...

Devi aggiungere l'intestazione della risposta HTTP:

Access-Control-Allow-Origin: *

Se lo fai, il risultato non è solo "potrebbe funzionare", ma "funzionerà".

NB Quello che devi aggiungere è un'intestazione di risposta HTTP , quindi puoi farlo solo su un server che controlli. Non sarà mai possibile recuperare direttamente http://w3schools.com/XML/cd_catalog.xml dal suo URL originale utilizzando un XMLHttpRequest(come da domanda dell'OP), perché quella risorsa non lo fa (almeno, non a partire dal 24 aprile 2015) includere qualsiasi intestazione CORS di questo tipo.

http://en.wikipedia.org/wiki/Cross-origin_resource_sharing fornisce maggiori informazioni.


0

Il mio problema simile a questo è stato risolto controllando il mio codice html. Avevo un onclickgestore nel mio pulsante di invio del modulo a un metodo. come questo: onclick="sendFalconRequestWithHeaders()". Questo metodo a sua volta chiama ajax proprio come il tuo e fa quello che voglio. Ma non come previsto, il mio browser non restituiva nulla.

Appreso dal duro lavoro di qualcuno , sono tornato falso in questo gestore e ho risolto. Permettetemi di dire che prima di arrivare a questo post, ho trascorso un intero fine settimana di 3 giorni e mezzo al giorno a scrivere codice ufficio attuazione CORS filters, jetty config, altra jersey and embedded jettyroba riferito - solo per risolvere questo problema, che ruota intorno a tutta la mia comprensione. cross domain ajax requestsE roba standard. Era ridicolo come semplici errori in javascript ti rendessero stupido.

Per essere vero, ho provato signed.applets.codebase_principal_support = truee scritto isLocalHost() **if**. potrebbe essere che questo metodo debba essere implementato da noi, firefox dice che non ce n'è ora devo pulire il mio codice per inviare la patch git in modo pulito. Grazie a quel qualcuno.


0

Una richiesta del browser "127.0.0.1/somefile.html" arriva invariata al server web locale, mentre "localhost / somefile.html" potrebbe arrivare come "0: 0: 0: 0: 0: 0: 0: 1 / somefile.html "se IPv6 è supportato. Quindi quest'ultimo può essere elaborato come passaggio da un dominio a un altro.


0

Alex Robinson e bmju hanno fornito preziose informazioni per comprendere i problemi di origine incrociata. Volevo aggiungere che potrebbe essere necessario effettuare una chiamata OPTIONS esplicita nel codice client prima di effettuare il GET / POST desiderato (ad es. Contro un endpoint del servizio OAuth CORS). Il tuo browser / libreria potrebbe non gestire automaticamente la richiesta OPTIONS. Gruber, questa è una delle possibili risposte alla tua domanda.


0

Ho avuto lo stesso problema (readyState era 4 e stato 0) , quindi ho seguito un approccio diverso spiegato in questo tutorial: https://spring.io/guides/gs/consuming-rest-jquery/

Non ha usato affatto XMLHttpRequest , invece ha usato il metodo 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>

e per il file public / hello.js (oppure puoi inserirlo direttamente nello stesso codice 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
Ti rendi conto che jQuery $.ajax()utilizza XMLHttpRequestall'interno, vero?
Manngo

0

Ho dovuto aggiungere (di nuovo) il mio indirizzo IP corrente alla whitelist Atlas MongoDB e quindi mi sono sbarazzato dell'errore di stato 0 di XMLHttpRequest


-1

Ho avuto questo problema perché l'ho usato 0.0.0.0come server, l'ho cambiato in localhoste funziona.


-4

Modifica: si prega di leggere i commenti di Malvolio di seguito poiché la conoscenza di questa risposta è obsoleta.

Non è possibile eseguire richieste XMLHttp tra domini.

La chiamata a 127.0.0.1funziona perché la tua pagina di test si trova in 127.0.0.1, e anche il test locale funziona poiché, beh ... è un test locale.

Gli altri due test falliscono perché JavaScript non può comunicare con un server distante tramite XMLHttpRequest.

Potresti invece considerare:

  • XMLHttp-richiedi il tuo server per recuperare il tuo contenuto XML remoto per te (script php, ad esempio)
  • Cercando di utilizzare un servizio come GoogleAppEngine se vuoi mantenerlo JavaScript completo.

spero che aiuti


40
Questo è semplicemente sbagliato. È possibile fare XMLHttpRequests tra domini.
Malvolio

1
"Non puoi" come in "Non dovresti farlo perché non è mai una buona idea"
Gabriel Sprenger

24
- abbastanza giusto, ma non so se un commento è il miglior forum per questo. Le XMLHttpRequest cross-domain hanno certamente alcune sfide alla sicurezza, ma offrono tutti gli strumenti necessari per affrontare queste sfide. A parte questo, consentono ai siti Web di offrire facilmente servizi ad altri siti Web, di utilizzare CDN per propagare i dati e di rispondere più rapidamente alle richieste degli utenti. Se hai domande specifiche, puoi inviarmi un messaggio o, meglio, pubblicare una domanda qui su SO e attirare la mia attenzione su di essa.
Malvolio

2
@GabrielSprenger: Cross-domain XMLHttpRequests non è solo una buona idea, è così comune oggigiorno che NON farlo in una moderna app web (oltre a qualche tipo di HelloWorlds) è qualcosa di ridicolo. Qualsiasi servizio REST esterno utilizzato dalla tua app richiede un interdominio XMLHttpRequest. Ed è per questo che è stata aggiunta tutta quella roba CORS.
Alexander Abakumov
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.