2011-09-12 12 views
10

Ecco un XMLHttpRequest esempio che ho messo insieme da w3schoolsXMLHttpRequest asincrono non funziona, restituisce sempre stato 0

<html> 
<head> 
<script type="text/javascript"> 
function loadXMLDoc() 
{ 
    var T="nothing"; 

    xmlhttp=new XMLHttpRequest(); 
    xmlhttp.overrideMimeType('text/plain'); // don't sc 
    xmlhttp.onreadystatechange=function() 
    { 
    alert ("rdystate: " + xmlhttp.readyState); 
    alert ("status: " + xmlhttp.status); 
    alert ("Text: "  + xmlhttp.statusText); 
    if (xmlhttp.readyState==4 && xmlhttp.status==200) 
    { 
     T = xmlhttp.responseText; 
    } 
    } 
xmlhttp.open("GET","SBL_PROBES.htm",true); 
xmlhttp.send(null); 
//T = xmlhttp.responseText; 
alert(T); 
} 
</script> 
</head> 
<body> 

<h2>Using the XMLHttpRequest object</h2> 
<div id="myDiv"></div> 
<button type="button" onclick="loadXMLDoc()">CHange Content</button> 

</body> 
</html> 

XMLHttpRequest restituisce sempre uno stato pari a zero.

Nulla si presenta nella console degli errori di Firefox.

Se cambio la richiesta a uno sincrona cambiando la riga

xmlhttp.open("GET","SBL_PROBES.htm",true); 

a

xmlhttp.open("GET","SBL_PROBES.htm",false); 

e non-commento della linea

//T = xmlhttp.responseText; 

Il testo del file richiesto viene restituito.

L'HTM e il file si trovano nella stessa directory. Se lo provi avrai bisogno anche di un file SBL_PROBES.htm, i contenuti sono irrilevanti.

Sto usando Firefox 3.6.22.

Potrebbe trattarsi di un problema interdominio? Se è così, perché funziona come una richiesta sincrona?

+3

Conferma che si sono sicuramente eseguendo questa pagina da un server Web, e non dal file system del computer locale. cioè, quando visiti la pagina di test nel tuo browser, vedi l'url che inizia con http e non con il file. – James

+2

Le mie scuse a tutti per averti disturbato con questo. Il mio problema era infatti che non stavo correndo attraverso il server ma come un file. In qualche modo, ho capito che perché avevo un file .htm stavo passando attraverso il server. Ho accettato la risposta del malvagio perché aveva la perseveranza di continuare a chiedermelo fino a quando non è penetrato nel mio grosso cranio :-) –

+0

https://developer.mozilla.org/En/XMLHttpRequest/Using_XMLHttpRequest Dai un'occhiata a "XMLHttpRequests che viene fermato" sezione. Sembra un errore UNSENT. –

risposta

15

È possibile utilizzare una funzione all'interno dell'istruzione if. Questa funzione viene eseguita modifiche quando readyState a 4.

var handleResponse = function (status, response) { 
    alert(response) 
} 
var handleStateChange = function() { 
    switch (xmlhttp.readyState) { 
     case 0 : // UNINITIALIZED 
     case 1 : // LOADING 
     case 2 : // LOADED 
     case 3 : // INTERACTIVE 
     break; 
     case 4 : // COMPLETED 
     handleResponse(xmlhttp.status, xmlhttp.responseText); 
     break; 
     default: alert("error"); 
    } 
} 
var xmlhttp=new XMLHttpRequest(); 
xmlhttp.onreadystatechange=handleStateChange; 
xmlhttp.open("GET","SBL_PROBES.htm",true); 
xmlhttp.send(null); 

tuo vecchio codice ha fatto una chiamata asincrona e ha continuato solo con la dichiarazione di avviso. T era vuoto in questo momento.

Ok, ti ​​spiego un po 'come funziona questa cosa:

In primo luogo abbiamo definire due funzioni di callback, che noi chiamiamo più avanti nella richiesta, di nome handleResponse e handleStateChange.

Successivamente creiamo un oggetto, che rappresenta il XMLHttpRequest

var xmlhttp=new XMLHttpRequest(); 

Ciò si traduce in un oggetto come segue (simplyfied):

XMLHttpRequest { status=0, readyState=0, multipart=false, onreadystatechange=handleEvent()} 

Con la funzione open (...) chiamare impostare i parametri per la richiesta:

xmlhttp.open("GET","SBL_PROBES.htm",true); 

Ciò significa eseguire una richiesta GET asincrona per recupera la pagina SBL_PROBES.htm Quindi viene chiamata la funzione di invio (...) che attiva la richiesta stessa.

Abbiamo registrato una funzione di callback per lo strumento onreadystat, come potete immaginare, questo è in realtà un eventHandler.Ogni volta che lo stato cambia questa funzione viene chiamata. (È lo stesso che se si registra una funzione di callback a un evento onKeyUp in un modulo, questa richiamata viene attivata ogni volta che si preme :))

L'unico caso che interessa al problema è stato 4 Pertanto, la funzione callback di handleRequest viene chiamata solo nello stato 4. In questo momento la richiesta ha effettivamente un risultato e un ulteriore stato. (Stato indica che il tuo server web ha restituito un codice di stato 200 = ok, 404 = non trovato ecc.)

Questa non è tutta la magia che sta dietro la roba di ajax, ma dovrebbe darti una panoramica semplificata, cosa sta accadendo dietro le scene. È importante testarlo su un server web, non utilizzare file: // per il test.

Se hai bisogno di maggiori informazioni in dettaglio, fammelo sapere.

+0

Non vedo MAI una chiamata sulla funzione dove readyState = 4 AND status non è zero. –

+0

Un problema alla volta. In handleResponse basta fare un avviso ("pippo"), l'avviso viene chiamato correttamente? Non preoccuparti dello stato in questo momento. Btw. puoi omettere "SBL_PROBES.htm". Basta inserire un "/" e controllare se viene chiamato l'avviso. – evildead

+0

Ok. Ho eliminato lo stato di controllo, controllando solo readyState == 4. L'avviso in handleStateChange mostra quindi T con il contenuto corretto. Anche l'altro avviso alla fine è uscito da quello in alto che non mostrava nulla. Quindi, come posso aspettare che la richiesta venga completata? –

3

È perché async ritorna prima che la richiesta ritorni. Le richieste sincrone vengono restituite al termine della richiesta.

Prova a manipolare la logica qui.

xmlhttp.onreadystatechange=function() 
    { 
    alert ("rdystate: " + xmlhttp.readyState); 
    alert ("status: " + xmlhttp.status); 
    alert ("Text: "  + xmlhttp.statusText); 
    if (xmlhttp.readyState==4 && xmlhttp.status==200) 
    { 
     T = xmlhttp.responseText; 
     alert(T); 
    } 
    } 
+0

Daniel A. White: mi dispiace non capisco, non ci arriviamo mai perché xmlhttp.status è sempre zero . –

+0

Alert is caps, changed to alert. :) – epascarello

8

Lo stato zero si verifica per due motivi.

  1. Si sta eseguendo il protocollo del file.
  2. Qualcosa sta postando indietro la pagina quando la richiesta Ajax è attiva.

Credo che stai vedendo il n. 2 qui. Quindi è necessario annullare il clic del pulsante.

<button type="button" onclick="loadXMLDoc(); return false;">CHange Content</button> 

Nel codice sopra di tale avviso (T) sarà sempre dicono nulla quando la richiesta è asincrona.

+0

Non fa differenza, lo stato è sempre zero. –

+0

Stai eseguendo questo da un server o dal tuo disco rigido [aka c: \ file.html]? Se è il tuo hardrive non vedrai mai 200. – epascarello

+0

+1 per "protocollo file" – James

0

Ho ricevuto la buona risposta a questo problema comune. Segue la risposta:

Questo è un problema molto comune durante lo sviluppo per il web. Ci sono due modi per aggirarlo.

  1. Il primo è utilizzare JSONP, che la nostra API supporta quando si aggiunge un parametro di query ("? Callback = foo"). Questo dovrebbe essere subito operativo ed è ottimo per lo sviluppo, ma non è sicuro per l'uso in produzione dal momento che gli utenti ottengono l'accesso alla chiave API.
  2. Il secondo (che è quello che usiamo su Forecast, ed è il miglior metodo per la produzione) è quello di impostare un server proxy sul proprio dominio che può effettuare richieste a Forecast per conto dell'utente. Questo mette in ombra la politica di origine identica del browser, impedisce agli utenti di accedere alla chiave API (che può essere archiviata lato server) e consente inoltre di utilizzare la memorizzazione nella cache delle richieste, se lo si desidera. (Il nostro server web preferito, NGINX, supporta questo esempio ed è davvero facile da configurare.Se hai bisogno di alcune configurazioni di esempio, faccelo sapere!)
1

Ho combattuto il problema di non ottenere un risultato quando si utilizza l'istruzione aperta asincrona XMLHttpRequest. Poiché questa domanda è la prima che ho trovato durante l'utilizzo di google, ecco come ho risolto:

Se si utilizza un pulsante all'interno di un modulo, assicurarsi che sia impostato su type = "submit" e onclick = "return myFunction()". E in myFunction(), assicurati di restituire false, non true! Restituendo true dalla funzione, si ricarica la pagina e l'oggetto XML scompare. Se si restituisce false, la richiesta XML ottiene il tempo necessario per completare e verrà eseguita la funzione onreadystatechange.

Fonte: Flask Mailing List

Problemi correlati