Điều này hầu như luôn đúng. Tuy nhiên, có một điểm khác biệt đáng kể là onreadystatechange
trình xử lý sự kiện cũng được kích hoạt readyState==4
trong các trường hợponerror
trình xử lý thường được kích hoạt (thường là sự cố kết nối mạng). Nó có trạng thái 0 trong trường hợp này. Tôi đã xác minh điều này xảy ra trên Chrome, Firefox và IE mới nhất.
Vì vậy, nếu bạn đang sử dụng onerror
và đang nhắm mục tiêu các trình duyệt hiện đại, bạn không nên sử dụng onreadystatechange
mà nên sử dụng onload
thay thế, có vẻ như được đảm bảo chỉ được gọi khi yêu cầu HTTP đã hoàn thành thành công (với phản hồi thực và mã trạng thái). Nếu không, bạn có thể nhận được hai trình xử lý sự kiện được kích hoạt trong trường hợp có lỗi (đó là cách tôi phát hiện ra theo kinh nghiệm về trường hợp đặc biệt này.)
Đây là liên kết đến chương trình thử nghiệm Plunker mà tôi đã viết cho phép bạn kiểm tra các URL khác nhau và xem chuỗi sự kiện và readyState
giá trị thực tế như ứng dụng JavaScript đã thấy trong các trường hợp khác nhau. Mã JS cũng được liệt kê bên dưới:
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();
}