web-dev-qa-db-fra.com

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

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

Ce devrait être la même chose. onload a été ajouté dans XMLHttpRequest 2 alors que onreadystatechange existe depuis la spécification d'origine.

61
J. K.

Ceci est presque toujours vrai. Une différence significative, cependant, est que le gestionnaire d'événements onreadystatechange est également déclenché avec readyState == 4 dans les cas où le gestionnaire onerror 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 onerror et ciblez les navigateurs modernes, vous ne devriez pas utiliser onreadystatechange mais plutôt onload, qui semble garanti d'être appelé uniquement lorsque la demande HTTP a abouti (avec une réponse et un code d'état réels). Sinon, deux gestionnaires d’événements risquent de se déclencher en cas d’erreur (c’est ce que j’ai découvert de manière empirique à propos de ce cas particulier.)

Voici un lien vers un programme de test Plunker que j’ai écrit et qui vous permet de tester différentes URL et de voir la séquence réelle des événements et les valeurs readyState telles que vues par l’application JavaScript dans différents cas. Le code JS est également indiqué 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();
}
144

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

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