Ist Onload in XMLHttpRequest gleich readyState == 4?

122

Ich bin verwirrt über das xhr-Rückgabeereignis, wie ich sehen kann, gibt es nicht so viele Unterschiede zwischen onreadystatechange -> readyState == 4 und onload, stimmt das?

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

xhr.send(null);

oder

xhr.onload = function() { /* do something */ }
Huang
quelle
13
Wenn jemand dies als Beispiel betrachtet, beachten Sie, dass es async = false verwendet (3. Argument von xhr.open) - was normalerweise nicht das ist, was Sie wollen.
Eddiewould

Antworten:

65

Es sollte dasselbe sein. onloadwurde in XMLHttpRequest 2 hinzugefügt, während onreadystatechangees seit der ursprünglichen Spezifikation existiert.

JK
quelle
Scheint, dass mobile Safari bei Verwendung von Onload nicht zurückkommt. onreadystatechange funktioniert jedoch.
Kai Hartmann
1
Es gibt keine wirklich klare Trennung mehr zwischen XHR 1 und XHR 2, sie haben sich zu einem Standard zusammengeschlossen. Die häufigste Funktion, die XHR 2 darstellt, ist die CORS-Unterstützung. Von diesem Standpunkt aus wurde XHR 2 erst in IE 10 angezeigt, aber XHR.onload wurde in IE 9 unterstützt, von dem normalerweise angenommen wird, dass es XHR 1 ist.
Chase
153

Das ist fast immer wahr. Ein wesentlicher Unterschied besteht jedoch darin, dass der onreadystatechangeEreignishandler auch readyState==4in den Fällen ausgelöst wird, in denen der onerrorHandler normalerweise ausgelöst wird (normalerweise ein Problem mit der Netzwerkkonnektivität). In diesem Fall erhält es den Status 0. Ich habe überprüft, ob dies auf den neuesten Versionen von Chrome, Firefox und IE geschieht.

Wenn Sie also onerrormoderne Browser verwenden und darauf abzielen, sollten Sie diese nicht verwenden, onreadystatechangesondern onloadstattdessen verwenden. Dies scheint garantiert nur dann aufgerufen zu werden, wenn die HTTP-Anforderung erfolgreich abgeschlossen wurde (mit einer echten Antwort und einem Statuscode). Andernfalls werden im Fehlerfall möglicherweise zwei Ereignishandler ausgelöst (so habe ich empirisch von diesem Sonderfall erfahren).

Hier ist ein Link zu einem von mir geschriebenen Plunker-Testprogramm , mit dem Sie verschiedene URLs testen und die tatsächliche Abfolge von Ereignissen und readyStateWerten anzeigen können, die von der JavaScript-App in verschiedenen Fällen angezeigt werden. Der JS-Code ist auch unten aufgeführt:

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();
}
Fernando Echeverria
quelle
2
@Fernando Um zu klären, nach innen onload, readyState === 4ist garantiert wahr richtig?
kgf3JfUtW
6
@sam Ja, das scheint immer der Fall zu sein, obwohl das Gegenteil eindeutig nicht der Fall ist, da es readyStatesich um 4 erroroder auch um abortFälle handeln kann. Dieser Zustand bedeutet im Grunde, dass der Ladevorgang erfolgreich abgeschlossen wurde oder nicht. Für ein normales, erfolgreiches Laden lautet die endgültige Abfolge der Ereignisse: progress(mit allen geladenen Daten), readystatechange(mit readyState == 4) load,, loadend.
Fernando Echeverria
2
Denken Sie daran, dass onloadauch nicht auslösen wird, wennNo 'Access-Control-Allow-Origin' header is present on the requested resource.
Deathangel908
Das ist richtig. Dies ist einer der Fälle, die den onerrorHandler auslösen.
Fernando Echeverria
1
@ Pacerier: Ja, bitte sehen Sie hier: plnkr Test
Fernando Echeverria
10

Nein, sie sind nicht gleich. Wenn Sie auf einen Netzwerkfehler stoßen oder den Vorgang abbrechen, onloadwird dieser nicht aufgerufen. Eigentlich ist das nächste Ereignis readyState === 4wäre loadend. Der Fluss sieht so aus:

     onreadystatechange
      readyState === 4
             
 onload / onerror / onabort
             
         onloadend
Benutzer
quelle