2012-02-07 5 views
94

Sono confuso circa l'evento di ritorno xhr, come posso dire, non ci sono molte differenze tra onreadystatechange -> readyState == 4 e onload, è vero?È onload uguale a readyState == 4 in XMLHttpRequest?

var xhr = new XMLHttpRequest(); 
xhr.open("Get", url, false); 
xhr.onreadystatechange = function() { 
    if (xhr.readyState === 4) 
    { 
     /* do some thing*/ 
    } 
}; 

xhr.send(null); 

o

xhr.onload = function() { /* do something */ } 
+3

Se qualcuno sta guardando questo come esempio nota che sta usando async = false (3 ° argomento di xhr.open) - che non è normalmente quello che ci vuole. – eddiewould

risposta

54

dovrebbe essere la stessa cosa. onload è stato aggiunto in XMLHttpRequest 2 mentre onreadystatechange è stato in circolazione dalle specifiche originali.

+0

Sembra che Safari mobile non ritorni quando si utilizza onload. onreadystatechange funziona, però. –

+1

Non c'è più una chiara separazione tra XHR 1 e XHR 2, si sono fusi in uno standard. La caratteristica più comune che rappresenta XHR 2 è il supporto CORS, quindi da quel punto di vista XHR 2 non è apparso in IE fino a IE 10 ma XHR.onload è stato supportato in IE 9, che in genere si ritiene essere XHR 1. – Chase

122

Questo è quasi uguale a sempre vero. Una differenza significativa, tuttavia, è che il gestore eventi onreadystatechange viene attivato anche con readyState == 4 nei casi in cui viene generalmente attivato il gestore onerror (in genere un problema di connettività di rete). In questo caso ottiene lo stato 0. Ho verificato che ciò avvenga sugli ultimi Chrome, Firefox e IE.

Quindi, se si utilizza onerror e stanno prendendo di mira i browser moderni, non si dovrebbe usare onreadystatechange ma dovrebbe usare onload invece, che sembra essere garantito per essere chiamato solo quando la richiesta HTTP ha completato con successo (con una vera e propria risposta e lo stato codice). Altrimenti potresti finire con l'attivazione di due gestori di eventi in caso di errori.

Ecco un link a un Plunker test program che ho scritto che ti permette di testare URL diversi e vedere il sequenza effettiva di eventi e valori readyState come visti dall'app JavaScript in diversi casi. Il codice JS è inoltre elencata di seguito:

var xhr; 
 
function test(url) { 
 
    xhr = new XMLHttpRequest(); 
 
    xhr.addEventListener("readystatechange", function() { log(xhr, "readystatechange") }); 
 
    xhr.addEventListener("loadstart", function(ev) { log(xhr, "loadstart", ev.loaded + " of " + ev.total) }); 
 
    xhr.addEventListener("progress", function(ev) { log(xhr, "progress", ev.loaded + " of " + ev.total) }); 
 
    xhr.addEventListener("abort", function() { log(xhr, "abort") }); 
 
    xhr.addEventListener("error", function() { log(xhr, "error") }); 
 
    xhr.addEventListener("load", function() { log(xhr, "load") }); 
 
    xhr.addEventListener("timeout", function(ev) { log(xhr, "timeout", ev.loaded + " of " + ev.total) }); 
 
    xhr.addEventListener("loadend", function(ev) { log(xhr, "loadend", ev.loaded + " of " + ev.total) }); 
 
    xhr.open("GET", url); 
 
    xhr.send(); 
 
} 
 

 
function clearLog() { 
 
    document.getElementById('log').innerHTML = ''; 
 
} 
 

 
function logText(msg) { 
 
    document.getElementById('log').innerHTML += msg + "<br/>"; 
 
} 
 

 
function log(xhr, evType, info) { 
 
    var evInfo = evType; 
 
    if (info) 
 
     evInfo += " - " + info ; 
 
    evInfo += " - readyState: " + xhr.readyState + ", status: " + xhr.status; 
 
    logText(evInfo); 
 
} 
 

 
function selected(radio) { 
 
    document.getElementById('url').value = radio.value; 
 
} 
 

 
function testUrl() { 
 
    clearLog(); 
 
    var url = document.getElementById('url').value; 
 
    if (!url) 
 
     logText("Please select or type a URL"); 
 
    else { 
 
     logText("++ Testing URL: " + url); 
 
     test(url); 
 
    } 
 
} 
 

 
function abort() { 
 
    xhr.abort(); 
 
}

+4

Questo dovrebbe essere accettato rispondi :) grazie per i dettagli –

+2

@Fernando per chiarire, all'interno di 'onload',' readyState === 4' è garantito che sia vero vero? – sam

+4

@sam Sì, sembra che sia sempre il caso, sebbene il contrario non sia chiaramente vero, dato che 'readyState' può essere 4 anche nei casi' error' o 'abort'. Questo stato significa fondamentalmente che il processo di caricamento è terminato, con successo o meno. Per un normale carico di successo, la sequenza finale di eventi è: 'progresso' (con tutti i dati caricati),' readystatechange' (con 'readyState == 4'),' load', 'loadend'. –

1

No, non sono la stessa cosa. Se si verifica un errore di rete o si interrompe l'operazione, onload non verrà chiamato. In realtà, l'evento più vicino a readyState === 4 sarebbe loadend. Il flusso è simile al seguente:

 onreadystatechange 
     readyState === 4 
      ⇓ 
onload/onerror/onabort 
      ⇓ 
     onloadend