Onload 等于 XMLHttpRequest 中的 readyState = = 4吗?

我对 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);

或者

xhr.onload = function() { /* do something */ }
61187 次浏览

应该是一样的。onload是在 XMLHttpRequest 2中添加的,而 onreadystatechange自最初的规范以来一直存在。

这是 差不多总是正确的。然而,一个重要的区别是,在通常触发 onerror处理程序(通常是网络连接问题)的情况下,onreadystatechange事件处理程序也会被 readyState==4触发。在这种情况下,它的状态为0。我已经在最新的 Chrome、 Firefox 和 IE 上验证了这一点。

因此,如果您正在使用 onerror,并且目标是现代浏览器,那么您不应该使用 onreadystatechange,而应该使用 onload,这似乎保证了只有当 HTTP 请求成功完成(使用真正的响应和状态代码)时才会调用 onload。否则,在出现错误的情况下,您可能最终会触发两个事件处理程序(我就是通过这种方式从经验中发现这种特殊情况的)

下面是我写的一个 普朗克测试程序链接,它允许您测试不同的 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();
}

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

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

在这里的简单代码中,他们是如何处理错误的

xhr.onload = function() {
// same or allowed cross origin
if (this.status == 200) {


}
else {} // error http status not 200
};
xhr.onerror = function() {
//error: cross origin, bad connection
};

VS

xhr.onreadystatechange = function() {
if (xhr.readyState === 4) {
if (this.status == 200) {


}
else {} // error: cross origin, http status not 200, bad connection
}
};