onload是否等于XMLHttpRequest中的readyState == 4?

Hua*_*ang 114 javascript ajax xmlhttprequest

我对xhr返回事件感到困惑,正如我所知,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);
Run Code Online (Sandbox Code Playgroud)

要么

xhr.onload = function() { /* do something */ }
Run Code Online (Sandbox Code Playgroud)

Fer*_*ria 148

几乎总是如此.但是,一个显着的区别是,在通常触发onerror处理程序(通常是网络连接问题)的情况下,onreadystatechange事件处理程序也会被readyState == 4触发.在这种情况下,它的状态为0.我已经在最新的Chrome,Firefox和IE上验证了这一点.

因此,如果您使用的是onerror并且目标是现代浏览器,则不应使用onreadystatechange,而应使用onload,这似乎只能在HTTP请求成功完成时(具有真实的响应和状态代码)被调用.否则,如果出现错误,您最终可能会触发两个事件处理程序(这是我根据经验发现的特殊情况).

以下是我编写的Plunker测试程序的链接,该程序允许您测试不同的URL,并查看JavaScript应用程序在不同情况下看到的事件和readyState值的实际顺序.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();
}
Run Code Online (Sandbox Code Playgroud)

  • @sam是的,似乎总是如此,虽然相反的情况显然不正确,因为`readyState`在'error`或`abort`情况下也可以是4.这个状态基本上意味着加载过程已经完成,无论是否成功.对于正常的成功加载,事件的最后一个序列是:`progress`(加载所有数据),`readystatechange`(使用`readyState == 4`),`load`,`loadend`. (6认同)
  • @Fernando为了澄清,在`onload`中,`readyState === 4`保证是正确的吗? (2认同)
  • 请记住,如果请求的资源上没有“ Access-Control-Allow-Origin”标头,则“ onload”也不会触发。 (2认同)

J. *_* K. 62

它应该是一回事.onload已添加到XMLHttpRequest 2中,而onreadystatechange自原始规范以来一直存在.


use*_*ser 6

不,他们不一样。如果遇到网络错误或中止操作,onload将不会被调用。实际上,最接近的事件readyState === 4loadend。流程如下所示:

     onreadystatechange
      readyState === 4
             ?
 onload / onerror / onabort
             ?
         onloadend
Run Code Online (Sandbox Code Playgroud)