这几乎总是正确的。然而,一个显着的区别是,在通常触发处理程序的情况下(通常是网络连接问题),onreadystatechange
也会触发事件处理程序。在这种情况下,它的状态为 0。我已经在最新的 Chrome、Firefox 和 IE 上验证了这种情况。readyState==4
onerror
因此,如果您正在使用onerror
并且针对的是现代浏览器,则不应使用onreadystatechange
而应该使用onload
它,这似乎可以保证仅在 HTTP 请求成功完成(具有真实响应和状态代码)时才会调用。否则,您可能最终会在出现错误时触发两个事件处理程序(这是我凭经验发现这种特殊情况的方式。)
这是我编写的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();
}