XMLHttpRequestのonloadはreadyState == 4に等しいですか?


122

私が知ることができるように、私はxhr returnイベントについて混乱しています、onreadystatechange- > readyState == 4とonloadの間にそれほど大きな違いはありません、それは本当ですか?

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

xhr.send(null);

または

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

13
誰かがこれを例として見ている場合、それはasync = false(xhr.openの3番目の引数)を使用していることに注意してください-これは通常は望んでいないことです。
eddiewould 2016年

回答:


65

それは同じものでなければなりません。onloadXMLHttpRequest 2で追加されましたがonreadystatechange、元の仕様以来存在しています。


onloadを使用してもモバイルSafariが戻らないようです。ただし、onreadystatechangeは機能します。
Kai Hartmann

1
XHR 1とXHR 2の間に明確な分離はもはや存在せず、それらは1つの標準に統合されました。XHR 2を表し、最も一般的な特徴は、CORSがその立場のXHR 2からそのサポートされるIE 10までIEに表示されませんでしたが、XHR.onloadは通常、XHR 1であると考えられているIE 9でサポートされていた
チェイス

153

これはほとんどの場合当てはまります。ただし、1つの大きな違いは、ハンドラーが通常トリガーされる場合(通常はネットワーク接続の問題)にonreadystatechangeもイベントハンドラーがトリガーreadyState==4されることonerrorです。この場合、ステータスは0になります。これが最新のChrome、Firefox、IEで発生することを確認しました。

したがって、onerror最新のブラウザーを使用していて、ターゲットにしている場合は、使用しないでonreadystatechangeください。onload代わりに使用する必要があります。これは、HTTPリクエストが正常に完了したときにのみ呼び出されることが保証されているようです(実際の応答とステータスコードを使用)。そうしないと、エラーが発生した場合に2つのイベントハンドラーがトリガーされる可能性があります(これが、この特別なケースについて経験的にわかった方法です)。

以下は、私が作成したPlunkerテストプログラムへのリンクです。このプログラムを使用すると、さまざまなURLをテストしreadyState、さまざまなケースでJavaScriptアプリで見られるイベントと値の実際のシーケンスを確認できます。JSコードも以下にリストされています。

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明確にするために、内部onloadreadyState === 4は、真実であることが保証されていますか?
kgf3JfUtW 2017年

6
@samはい、それは常にそうであるように見えますが、readyState4 errorつ以上のabortケースのように、その反対は明らかに真実ではありません。この状態は、ロードプロセスが成功したかどうかに関係なく、基本的に終了したことを意味します。通常、成功した負荷のために、イベントの最終シーケンスは次のとおりです。progress(ロードされたすべてのデータを持つ)、 readystatechange(とreadyState == 4)、 、。load loadend
Fernando Echeverria

2
次のonload場合もトリガーされないことにNo 'Access-Control-Allow-Origin' header is present on the requested resource.
注意してください

それは本当だ。これは、onerrorハンドラーをトリガーするケースの1つです。
Fernando Echeverria 2017

1
@Pacerier:はい、こちらをご覧ください:plnkrテスト
Fernando Echeverria

10

いいえ、同じではありません。ネットワークエラーが発生した場合、または操作を中止した場合、onloadは呼び出されません。実際には、に最も近いイベントはにreadyState === 4なりますloadend。フローは次のようになります。

     onreadystatechange
      readyState === 4
             
 onload / onerror / onabort
             
         onloadend
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.