XMLHTTPRequest
XMLHTTPRequest
XMLHttpRequest是Ajax技術體系中最為核心的技術。缺少了它,Ajax的其餘技術就無法成為一個有機的整體,將會土崩瓦解。
目錄
XMLHttpRequest 得到了所有現代瀏覽器較好的支持。唯一的瀏覽器依賴性涉及 XMLHttpRequest 對象的創建。在 IE 5 和 IE 6 中,必須使用特定於 IE 的 ActiveXObject() 構造函數。正如在 XMLHttpRequest 對象 這一節所介紹的。
XMLHttpRequest 對象還沒有標準化,但是 W3C 已經開始了標準化的工作,本手冊介紹的內容都是基於標準化的工作草案。
當前的 XMLHttpRequest 實現已經相當一致。但是和標準有細微的不同。例如,一個實現可能返回 null,而標準要求是空字元串,或者實現可能把 readyState 設置為 3 而不保證所有的響應頭部都可用。
不同的瀏覽器使用不同的方法來創建 XMLHttpRequest 對象。
Internet Explorer 使用 ActiveXObject。
其他瀏覽器使用名為 XMLHttpRequest 的 JavaScript 內建對象。
要克服這個問題,可以使用這段簡單的代碼:
var XMLHttp=null;
if (window.XMLHttpRequest)
{
XMLHttp=new XMLHttpRequest()
}else if (window.ActiveXObject)
{
XMLHttp=new ActiveXObject("Microsoft.XMLHTTP")
}
代碼解釋:
首先創建一個作為 XMLHttpRequest 對象使用的 XMLHttp 變數。把它的值設置為 null。
如果可用,則用它創建一個新對象:XMLHttp=new XMLHttpRequest()
如果不可用,則檢測 window.ActiveXObject 是否可用。在 Internet Explorer version 5.5 及更高的版本中,該對象是可用的。
如果可用,使用它來創建一個新對象:XMLHttp=new ActiveXObject()
一些程序員喜歡使用最新最快的版本的 XMLHttpRequest 對象。
下面的例子試圖載入微軟最新版本的 "Msxml2.XMLHTTP",在 Internet Explorer 6 中可用,如果無法載入,則後退到 "Microsoft.XMLHTTP",在 Internet Explorer 5.5 及其後版本中可用。
function GetXmlHttpObject()
{
var xmlHttp=null;
try {
// Firefox, Opera 8.0+, Safari
xmlHttp=new XMLHttpRequest();
}
catch (e)
{
// Internet Explorer
try {
xmlHttp=new ActiveXObject("Msxml2.XMLHTTP");
}
catch (e) {
xmlHttp=new ActiveXObject("Microsoft.XMLHTTP");
}
}
return xmlHttp;
}
代碼解釋:
首先創建用作 XMLHttpRequest 對象的 XMLHttp 變數。把它的值設置為 null。
按照 web 標準創建對象 (Mozilla, Opera 以及 Safari):XMLHttp=new XMLHttpRequest()
按照微軟的方式創建對象,在 Internet Explorer 6 及更高的版本可用:XMLHttp=new ActiveXObject("Msxml2.XMLHTTP")
如果捕獲錯誤,則嘗試更老的方法 (Internet Explorer 5.5) :XMLHttp=new ActiveXObject("Microsoft.XMLHTTP")
HTTP 請求的狀態。當一個 XMLHttpRequest 初次創建時,這個屬性的值從 0 開始,直到接收到完整的 HTTP 響應,這個值增加到 4。
5 個狀態中每一個都有一個相關聯的非正式的名稱,下表列出了狀態、名稱和含義:
狀態 | 名稱 | 描述 |
Uninitialized | 初始化狀態。XMLHttpRequest 對象已創建或已被 abort() 方法重置。 | |
1 | Open | open() 方法已調用,但是 send() 方法未調用。請求還沒有被發送。 |
2 | Send | Send() 方法已調用,HTTP 請求已發送到 Web 伺服器。未接收到響應。 |
3 | Receiving | 所有響應頭部都已經接收到。響應體開始接收但未完成。 |
4 | Loaded | HTTP 響應已經完全接收。 |
readyState 的值不會遞減,除非當一個請求在處理過程中的時候調用了 abort() 或 open() 方法。每次這個屬性的值增加的時候,都會觸發 onreadystatechange 事件句柄。
目前為止從伺服器接收到的響應體(不包括頭部),或者如果還沒有接收到數據的話,就是空字元串。
如果 readyState 小於 3,這個屬性就是一個空字元串。當 readyState 為 3,這個屬性返回目前已經接收的響應部分。如果 readyState 為 4,這個屬性保存了完整的響應體。
對請求的響應,解析為 XML 並作為 Document 對象返回。
由伺服器返回的 HTTP 狀態代碼,如 200 表示成功,而 404 表示 "Not Found" 錯誤。當 readyState 小於 3 的時候讀取這一屬性會導致一個異常。
這個屬性用名稱而不是數字指定了請求的 HTTP 的狀態代碼。也就是說,當狀態為 200 的時候它是 "OK",當狀態為 404 的時候它是 "Not Found"。和 status 屬性一樣,當 readyState 小於 3 的時候讀取這一屬性會導致一個異常。
onreadystatechange:
每次 readyState 屬性改變的時候調用的事件句柄函數。當 readyState 為 3 時,它也可能調用多次。
取消當前響應,關閉連接並且結束任何未決的網路活動。
這個方法把 XMLHttpRequest 對象重置為 readyState 為 0 的狀態,並且取消所有未決的網路活動。例如,如果請求用了太長時間,而且響應不再必要的時候,可以調用這個方法。
把 HTTP 響應頭部作為未解析的字元串返回。
如果 readyState 小於 3,這個方法返回 null。否則,它返回伺服器發送的所有 HTTP 響應的頭部。頭部作為單個的字元串返回,一行一個頭部。每行用換行符 "\r\n" 隔開。
返回指定的 HTTP 響應頭部的值。其參數是要返回的 HTTP 響應頭部的名稱。可以使用任何大小寫來制定這個頭部名字,和響應頭部的比較是不區分大小寫的。
該方法的返回值是指定的 HTTP 響應頭部的值,如果沒有接收到這個頭部或者 readyState 小於 3 則為空字元串。如果接收到多個有指定名稱的頭部,這個頭部的值被連接起來並返回,使用逗號和空格分隔開各個頭部的值。
初始化 HTTP 請求參數,例如 URL 和 HTTP 方法,但是並不發送請求。
發送 HTTP 請求,使用傳遞給 open() 方法的參數,以及傳遞給該方法的可選請求體。
向一個打開但未發送的請求設置或添加一個 HTTP 請求。
初始化 HTTP 請求參數
url 參數是請求的主體。大多數瀏覽器實施了一個同源安全策略,並且要求這個 URL 與包含腳本的文本具有相同的主機名和埠。
async 參數指示請求使用應該非同步地執行。如果這個參數是 false,請求是同步的,後續對 send() 的調用將阻塞,直到響應完全接收。如果這個參數是 true 或省略,請求是非同步的,且通常需要一個 onreadystatechange 事件句柄。
username 和 password 參數是可選的,為 url 所需的授權提供認證資格。如果指定了,它們會覆蓋 url 自己指定的任何資格。
這個方法初始化請求參數以供 send() 方法稍後使用。它把 readyState 設置為 1,刪除之前指定的所有請求頭部,以及之前接收的所有響應頭部,並且把 responseText、responseXML、status 以及 statusText 參數設置為它們的默認值。當 readyState 為 0 的時候(當 XMLHttpRequest 對象剛創建或者 abort() 方法調用后)以及當 readyState 為 4 時(已經接收響應時),調用這個方法是安全的。當針對任何其他狀態調用的時候,open() 方法的行為是為指定的。
除了保存供 send() 方法使用的請求參數,以及重置 XMLHttpRequest 對象以便復用,open() 方法沒有其他的行為。要特別注意,當這個方法調用的時候,實現通常不會打開一個到 Web 伺服器的網路連接。
發送一個 HTTP 請求
send(body)如果通過調用 open() 指定的 HTTP 方法是 POST 或 GET,body 參數指定了請求體,作為一個字元串或者 Document 對象。如果請求體不是必須的話,這個參數就為 null。對於任何其他方法,這個參數是不可用的,應該為 null(有些實現不允許省略該參數)。
這個方法導致一個 HTTP 請求發送。如果之前沒有調用 open(),或者更具體地說,如果 readyState 不是 1,send() 拋出一個異常。否則,它發送一個 HTTP 請求,該請求由以下幾部分組成:
之前調用 open() 時指定的 HTTP 方法、URL 以及認證資格(如果有的話)。之前調用 setRequestHeader() 時指定的請求頭部(如果有的話)。傳遞給這個方法的 body 參數。一旦請求發布了,send() 把 readyState 設置為 2,並觸發 onreadystatechange 事件句柄。
如果之前調用的 open() 參數 async 為 false,這個方法會阻塞並不會返回,直到 readyState 為 4 並且伺服器的響應被完全接收。否則,如果 async 參數為 true,或者這個參數省略了,send() 立即返回,並且正如後面所介紹的,伺服器響應將在一個後台線程中處理。
如果伺服器響應帶有一個 HTTP 重定向,send() 方法或後台線程自動遵從重定向。當所有的 HTTP 響應頭部已經接收,send() 或後台線程把 readyState 設置為 3 並觸發 onreadystatechange 事件句柄。如果響應較長,send() 或後台線程可能在狀態 3 中觸發 onreadystatechange 事件句柄:這可以作為一個下載進度指示器。最後,當響應完成,send() 或後台線程把 readyState 設置為 4,並最後一次觸發事件句柄。
value 參數是頭部的值。這個參數不應該包括換行。
setRequestHeader() 方法指定了一個 HTTP 請求的頭部,它應該包含在通過後續 send() 調用而發布的請求中。這個方法只有當 readyState 為 1 的時候才能調用,例如,在調用了 open() 之後,調用 send() 之前。
如果帶有指定名稱的頭部已經被指定了,這個頭部的新值就是:之前指定的值,加上逗號、空格以及這個調用指定的值。