Onload è uguale a readyState == 4 in XMLHttpRequest?


122

Sono confuso riguardo all'evento di ritorno xhr, come posso dire, non ci sono così tante differenze tra onreadystatechange -> readyState == 4 e onload, è vero?

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 */ }

13
Se qualcuno sta guardando questo come un esempio, nota che sta usando async = false (terzo argomento di xhr.open) - che normalmente non è quello che vorresti.
Eddiewould

Risposte:


65

Dovrebbe essere la stessa cosa. onloadè stato aggiunto in XMLHttpRequest 2 mentre esisteva onreadystatechangedalle specifiche originali.


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

1
Non esiste più una separazione netta e netta 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 questo punto di vista XHR 2 non è apparso in IE fino a IE 10 ma XHR. Onload era supportato in IE 9, che in genere è ritenuto XHR 1.
Chase

153

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

Quindi, se stai usando onerrore stai prendendo di mira i browser moderni, non dovresti usare onreadystatechangema dovresti usare onloadinvece, che sembra essere garantito per essere chiamato solo quando la richiesta HTTP è stata completata con successo (con una risposta reale e un codice di stato). Altrimenti potresti finire per ottenere due gestori di eventi attivati ​​in caso di errori (che è il modo in cui ho scoperto empiricamente questo caso speciale).

Di seguito è riportato un collegamento a un programma di test Plunker che ho scritto che consente di testare URL diversi e vedere la sequenza effettiva di eventi e readyStatevalori così come viene visualizzata dall'app JavaScript in casi diversi. Il codice JS è anche elencato 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();
}

2
@Fernando Per chiarire, dentro onload, readyState === 4è garantito che sia vero vero?
kgf3JfUtW

6
@sam Sì, sembra essere sempre così, anche se il contrario non è chiaramente vero, come readyStatepuò essere anche 4 erroro abortcasi. Questo stato fondamentalmente significa che il processo di caricamento è terminato, con successo o meno. Per un caricamento normale e riuscito, la sequenza finale di eventi è: progress(con tutti i dati caricati), readystatechange(con readyState == 4) load,, loadend.
Fernando Echeverria

2
Tieni presente che onloadanche questo non si attiverà seNo 'Access-Control-Allow-Origin' header is present on the requested resource.
deathangel908

È vero. Questo è uno dei casi che innesca il onerrorgestore.
Fernando Echeverria

1
@Pacerier: Sì, guarda qui: test plnkr
Fernando Echeverria

10

No, non sono la stessa cosa. Se si verifica un errore di rete o si interrompe l'operazione, onloadnon verrà richiamato. In realtà, l'evento più vicino readyState === 4sarebbe loadend. Il flusso si presenta così:

     onreadystatechange
      readyState === 4
             
 onload / onerror / onabort
             
         onloadend
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.