XMLHttpRequest'teki onload readyState == 4'e eşit mi?


122

Xhr dönüş olayıyla ilgili kafam karıştı, anlayabildiğim gibi onreadystatechange -> readyState == 4 ile onload arasında çok fazla fark yok , bu doğru mu?

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

xhr.send(null);

veya

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

13
Biri buna örnek olarak bakıyorsa, async = false (xhr.open'ın 3. argümanı) kullandığına dikkat edin - ki bu normalde istediğiniz şey değildir.
eddiewould

Yanıtlar:


66

Aynı şey olmalı. onloadXMLHttpRequest 2'ye eklendi, oysa onreadystatechangeorijinal spesifikasyondan beri var.


Görünüşe göre, mobil Safari, onload kullanılırken geri gelmiyor. onreadystatechange işe yarıyor.
Kai Hartmann

1
Artık XHR 1 ve XHR 2 arasında gerçek net bir ayrım yok, bunlar tek bir standartta birleştirildi. XHR 2'yi temsil eden en yaygın özellik CORS desteğidir, bu nedenle XHR 2, IE 10'a kadar IE'de görünmedi, ancak XHR.onload tipik olarak XHR 1 olduğuna inanılan IE 9'da desteklendi.
Chase

153

Bu neredeyse her zaman doğrudur. Bununla birlikte, önemli bir fark, işleyicinin genellikle tetiklendiği durumlarda (tipik olarak bir ağ bağlantısı sorunu) onreadystatechangeolay işleyicisinin de tetiklenmesidir . Bu durumda 0 statüsü alır. Bunun en son Chrome, Firefox ve IE'de olduğunu doğruladım.readyState==4onerror

Bu nedenle onerror, modern tarayıcıları kullanıyorsanız ve hedefliyorsanız, onreadystatechangekullanmamalısınız, onloadbunun yerine kullanmalısınız ; bu, yalnızca HTTP isteği başarıyla tamamlandığında (gerçek bir yanıt ve durum kodu ile) çağrılacağı garanti edilir. Aksi takdirde, hata durumunda tetiklenen iki olay işleyicisine sahip olabilirsiniz (bu, bu özel durumu deneysel olarak bu şekilde öğrendim.)

İşte yazdığım bir Plunker test programına , farklı URL'leri test etmenize readyStateve JavaScript uygulaması tarafından farklı durumlarda görülen gerçek olay ve değer sırasını görmenize olanak tanıyan bir bağlantı . JS kodu da aşağıda listelenmiştir:

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
, İçini aydınlatmak için @Fernando onload, readyState === 4gerçek hakkını olması sağlanır?
kgf3JfUtW

6
@sam Evet, bu her zaman böyle görünüyor, ancak bunun tersi açıkça doğru değil, readyState4 errorveya abortdurumlarda da olabilir. Bu durum, temelde yükleme işleminin başarılı olsun ya da olmasın bittiği anlamına gelir. Normal, başarılı bir yükleme için, son olay dizisi: progress(tüm veriler yüklenmiş olarak), readystatechange(ile readyState == 4) load,, loadend.
Fernando Echeverria

2
Bunun onloadda tetiklenmeyeceğini unutmayınNo 'Access-Control-Allow-Origin' header is present on the requested resource.
deathangel908

Bu doğru. onerrorİşleyiciyi tetikleyen durumlardan biri budur .
Fernando Echeverria

1
@Pacerier: Evet, lütfen buraya bakın: plnkr testi
Fernando Echeverria

11

Hayır, onlar aynı değil. Bir ağ hatasıyla karşılaşırsanız veya işlemi iptal ederseniz, onloadçağrılmayacaktır. Aslında en yakın olay readyState === 4olurdu loadend. Akış şuna benzer:

     onreadystatechange
      readyState === 4
             
 onload / onerror / onabort
             
         onloadend
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.