Onload est-il égal à readyState == 4 dans XMLHttpRequest?

122

Je suis confus au sujet de l'événement de retour xhr, comme je peux le dire, il n'y a pas tellement de différence entre onreadystatechange -> readyState == 4 et onload, est-ce vrai?

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

xhr.send(null);

ou

xhr.onload = function() { /* do something */ }
Huang
la source
13
Si quelqu'un regarde cela comme un exemple, notez qu'il utilise async = false (3e argument de xhr.open) - ce qui n'est normalement pas ce que vous voudriez.
eddiewould

Réponses:

65

Ça devrait être la même chose. onloada été ajouté dans XMLHttpRequest 2 alors qu'il onreadystatechangeexiste depuis la spécification d'origine.

JK
la source
Il semble que Safari mobile ne revient pas lors de l'utilisation de onload. onreadystatechange fonctionne, cependant.
Kai Hartmann
1
Il n'y a plus vraiment de séparation claire entre XHR 1 et XHR 2, ils ont fusionné en un seul standard. La fonctionnalité la plus courante qui représente XHR 2 est la prise en charge de CORS, donc de ce point de vue, XHR 2 n'est pas apparu dans IE avant IE 10, mais XHR.onload était pris en charge dans IE 9, qui est généralement considéré comme XHR 1.
Chase
153

C'est presque toujours vrai. Une différence significative, cependant, est que le onreadystatechangegestionnaire d'événements est également déclenché readyState==4dans les cas où le onerrorgestionnaire est généralement déclenché (généralement un problème de connectivité réseau). Il obtient le statut 0 dans ce cas. J'ai vérifié que cela se produit sur les derniers Chrome, Firefox et IE.

Donc, si vous utilisez onerroret ciblez des navigateurs modernes, vous ne devriez pas utiliser onreadystatechangemais onloadplutôt utiliser , ce qui semble être garanti uniquement lorsque la requête HTTP s'est terminée avec succès (avec une réponse réelle et un code d'état). Sinon, vous risquez de déclencher deux gestionnaires d'événements en cas d'erreurs (c'est ainsi que j'ai découvert empiriquement ce cas particulier.)

Voici un lien vers un programme de test Plunker que j'ai écrit qui vous permet de tester différentes URL et de voir la séquence réelle des événements et des readyStatevaleurs vues par l'application JavaScript dans différents cas. Le code JS est également répertorié ci-dessous:

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
la source
2
@Fernando Pour clarifier, à l'intérieur onload, il readyState === 4est garanti que c'est vrai, non?
kgf3JfUtW
6
@sam Oui, cela semble toujours être le cas, bien que le contraire ne soit clairement pas vrai, comme cela readyStatepeut être 4 sur errorou des abortcas aussi. Cet état signifie essentiellement que le processus de chargement est terminé, qu'il soit réussi ou non. Pour un chargement normal et réussi, la dernière séquence d'événements est: progress(avec toutes les données chargées), readystatechange(avec readyState == 4) load,, loadend.
Fernando Echeverria
2
Gardez à l'esprit que onloadcela ne déclenchera pas non plus siNo 'Access-Control-Allow-Origin' header is present on the requested resource.
deathangel908
C'est vrai. C'est l'un des cas qui déclenche le onerrorgestionnaire.
Fernando Echeverria
1
@Pacerier: Oui, s'il vous plaît voir ici: test plnkr
Fernando Echeverria
10

Non, ils ne sont pas les mêmes. Si vous rencontrez une erreur réseau ou abandonnez l'opération, onloadne sera pas appelé. En fait, l'événement le plus proche readyState === 4serait loadend. Le flux ressemble à ceci:

     onreadystatechange
      readyState === 4
             
 onload / onerror / onabort
             
         onloadend
utilisateur
la source