2012-02-07 31 views
94

Tôi nhầm lẫn về sự kiện trả lại xhr, như tôi có thể nói, không có quá nhiều sự khác biệt giữa onreadystatechange -> readyState == 4 và onload, có đúng không?Tải trọng bằng readyState == 4 trong XMLHttpRequest?

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

xhr.send(null); 

hoặc

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

Nếu có ai đang nhìn này là một ví dụ lưu ý rằng nó sử dụng async = false (tranh luận thứ 3 của xhr.open) - mà không phải là bình thường những gì bạn muốn. – eddiewould

Trả lời

54

Nó sẽ được điều tương tự. onload đã được thêm vào trong XMLHttpRequest 2 trong khi onreadystatechange đã xuất hiện từ thông số gốc.

+0

Dường như, Safari di động không quay lại khi sử dụng tải. onreadystatechange hoạt động, mặc dù. –

+1

Không có sự phân biệt rõ ràng giữa XHR 1 và XHR 2 nữa, chúng đã được hợp nhất thành một tiêu chuẩn. Các tính năng phổ biến nhất đại diện cho XHR 2 là hỗ trợ CORS do đó từ quan điểm XHR 2 đã không xuất hiện trong IE cho đến khi IE 10 nhưng XHR.onload được hỗ trợ trong IE 9 mà thường được cho là XHR 1. – Chase

122

Đây là gần như luôn đúng. Tuy nhiên, một sự khác biệt đáng kể là trình xử lý sự kiện onreadystatechange cũng được kích hoạt với readyState == 4 trong các trường hợp xử lý onerror thường được kích hoạt (thường là vấn đề kết nối mạng). Nó có trạng thái là 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 trình duyệt hiện đại, bạn không nên sử dụng onreadystatechange nhưng nên sử dụng onload thay vào đó, có vẻ như được đảm bảo chỉ được gọi khi yêu cầu HTTP hoàn tất thành công (với phản hồi và trạng thái thực mã). Nếu không, bạn có thể sẽ nhận được hai trình xử lý sự kiện được kích hoạt trong trường hợp xảy ra lỗi (đó là cách mà tôi đã phát hiện ra về trường hợp đặc biệt này.)

Đây là một liên kết đến một số Plunker test program Tôi đã cho phép bạn kiểm tra các URL khác nhau và xem chuỗi sự kiện thực tế và các giá trị readyState được ứng dụng JavaScript nhìn thấy trong các trường hợp khác nhau. Mã JS cũng được liệt kê dưới đây:

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(); 
 
}

+4

Điều này cần được chấp nhận Trả lời :) cảm ơn cho các chi tiết –

+2

@Fernando Để làm rõ, bên trong 'onload',' readyState === 4' được đảm bảo là đúng? – sam

+4

@sam Có, điều đó dường như luôn luôn xảy ra, mặc dù điều ngược lại rõ ràng là không đúng, vì 'readyState' có thể là 4 trong trường hợp' error' hoặc 'abort'. Trạng thái này về cơ bản có nghĩa là quá trình tải đã kết thúc, dù thành công hay không. Đối với một tải bình thường, thành công, chuỗi cuối cùng của sự kiện là: 'progress' (với tất cả các dữ liệu được nạp),' readystatechange' (với 'readyState == 4'),' load', 'loadend'. –

1

Không, họ không giống nhau. Nếu bạn gặp lỗi mạng hoặc hủy bỏ hoạt động, onload sẽ không được gọi. Trên thực tế, sự kiện gần nhất với readyState === 4 sẽ là loadend. Dòng chảy trông như thế này:

 onreadystatechange 
     readyState === 4 
      ⇓ 
onload/onerror/onabort 
      ⇓ 
     onloadend 
Các vấn đề liên quan