XMLHttpRequest對象是Ajax技術(shù)的核心。在Internet Explorer 5中,XMLHttpRequest對象以ActiveX對象引入,被稱(chēng)之為XMLHTTP,它是一種支持異步請求的技術(shù)。后來(lái)Mozilla、Netscape、Safari、Firefox和其他瀏覽器也提供了XMLHttpRequest類(lèi),雖然這些瀏覽器都提供了XMLHttpRequest類(lèi),但它們創(chuàng )建XMLHttpRequest類(lèi)的方法并不相同。XMLHttpRequest使我們可以使用JavaScript向服務(wù)器提出請求并處理響應,而不阻塞用戶(hù)的其他操作。
不刷新頁(yè)面就和服務(wù)器進(jìn)行交互是Ajax最大的特點(diǎn)。這個(gè)重要的特點(diǎn)主要歸功于XMLHttpRequest對象。使用XMLHttpRequest對象使得網(wǎng)頁(yè)應用程序像
windows應用程序一樣,能夠及時(shí)響應用戶(hù)與服務(wù)器之間的交互,不必進(jìn)行頁(yè)面刷新或者跳轉,并且能夠進(jìn)行一系列的數據處理,這些功能可以使用戶(hù)的等待時(shí)間縮短,同時(shí)也減輕了服務(wù)器端的負載。
目前XMLHttpRequest對象已經(jīng)得到了大部分瀏覽器的支持,因此使用Ajax技術(shù)開(kāi)發(fā)Web應用程序的時(shí)候一般情況下不會(huì )出現問(wèn)題。不過(guò),當開(kāi)發(fā)人員確定使用Ajax技術(shù)來(lái)開(kāi)發(fā)時(shí),仍然需要考慮用戶(hù)會(huì )使用什么樣的瀏覽器來(lái)對網(wǎng)站進(jìn)行訪(fǎng)問(wèn),雖然不支持XMLHttpRequest對象的瀏覽器占少數。
在使用XMLHttpRequest對象向服務(wù)器發(fā)送請求和處理響應之前,必修先用JavaScript創(chuàng )建一個(gè)XMLHttpRequest對象,然后通過(guò)這個(gè)對象來(lái)和服務(wù)器建立請求并接收服務(wù)器返回的數據。由于XMLHttpRequest不是一個(gè)W3C標準,所以可以采用多種方法使用JavaScript來(lái)創(chuàng )建XMLHttpRequest的實(shí)例。Internet Explorer把XMLHttpRequest實(shí)現為一個(gè)ActiveX對象,其他瀏覽器(如Firefox、Safari和Opera等)把它實(shí)現為一個(gè)本地JavaScript對象。由于存在這些差別,JavaScript代碼中必須包含有關(guān)的邏輯,從而使用ActiveX技術(shù)或者使用本地JavaScript對象技術(shù)來(lái)創(chuàng )建XMLHttpRequest的一個(gè)實(shí)例。
正因為在不同的瀏覽器中,XMLHttpRequest對象的創(chuàng )建方式不同,因此在程序中創(chuàng )建XMLHttpRequest對象之前需要對瀏覽器進(jìn)行判斷。使用詳細編寫(xiě)代碼方式來(lái)區別瀏覽器類(lèi)型的方式不僅代碼量大,而且很不方便也不靈活。在這里我們可以換一種思路來(lái)解決,只需要檢查瀏覽器是否提供對ActiveX對象的支持即可。如果瀏覽器支持ActiveX對象,就可以使用ActiveX來(lái)創(chuàng )建XMLHttpRequest對象。否則,就需要在程序中使用本地JavaScript對象技術(shù)來(lái)創(chuàng )建。下面的代碼展示了在不同的瀏覽器中使用JavaScript代碼來(lái)創(chuàng )建XMLHttpRequest對象的編程方法。
#001 function createXMLHttpRequest()
#002 {
#003 var xmlreq = false;
#004 if (window.ActiveXObject)
#005 {
#006 xmlreq = new ActiveXObject("Microsoft.XMLHTTP");
#007 }
#008 else if (window.XMLHttpRequest)
#009 {
#010 xmlreq = new XMLHttpRequest();
#011 }
#012 return xmlreq;
#013 }
我們從上面代碼中看出,創(chuàng )建XMLHttpRequest對象的過(guò)程比較簡(jiǎn)單。首先在createXMLHttpRequest()方法中創(chuàng )建了一個(gè)變量xmlreq來(lái)保存對這個(gè)對象的引用,并將其默認值設置為false。然后在這個(gè)方法中通過(guò)簡(jiǎn)單的判斷,確定究竟使用什么方法來(lái)創(chuàng )建對象。由于用戶(hù)使用的瀏覽器類(lèi)型不同,代碼window.ActiveXObject可能返回一個(gè)對象,也可能返回null。If條件語(yǔ)句根據返回的結果來(lái)判斷瀏覽器是否能支持ActiveX控件,相應地得知瀏覽器是IE還是其他瀏覽器類(lèi)型。如果判定用戶(hù)使用的是IE瀏覽器,則通過(guò)實(shí)例化ActiveXObject的一個(gè)實(shí)例的方法來(lái)創(chuàng )建XMLHttpRequest對象。使用這種方法時(shí),參數字符串指明要創(chuàng )建何種類(lèi)型的ActiveX對象。在本例子中,參數是Microsoft.XMLHTTP,這說(shuō)明需要創(chuàng )建的是XMLHttpRequest的一個(gè)實(shí)例。
如果window.ActiveXObject返回null,表示用戶(hù)使用的瀏覽器不支持ActiveX對象,那么程序會(huì )執行else語(yǔ)句所指定的操作。首先判斷瀏覽器是否把XMLHttpRequest實(shí)現為本地JavaScript對象。如果存在window.XMLHttpRequest,那么就創(chuàng )建XMLHttpRequest對象。最后將這個(gè)xmlreq變量返回,完成了XMLHttpRequest對象的創(chuàng )建過(guò)程。
由于JavaScript具有動(dòng)態(tài)類(lèi)型的特性,而且XMLHttpRequest對象在不同瀏覽器上的實(shí)現是兼容的,所有可以用同樣的方式訪(fǎng)問(wèn)XMLHttpRequest實(shí)例的屬性和方法,而不論這個(gè)實(shí)例創(chuàng )建的方法是什么。這就大大簡(jiǎn)化了開(kāi)發(fā)過(guò)程,而且在JavaScript中也不必編寫(xiě)特定于瀏覽器的邏輯。
XMLHttpRequest對象的屬性
XMLHttpRequest對象提供了許多屬性,處理XMLHttpRequest時(shí)需要頻繁用到這些屬性,如下表所示:
屬性
描述
onreadystatechange
每個(gè)狀態(tài)改變時(shí)都會(huì )觸發(fā)這個(gè)事件處理程序,通常會(huì )調用一個(gè)JavaScript函數
readyState
請求的狀態(tài)
responseText
服務(wù)器的響應,表示為一個(gè)串
responseXML
服務(wù)器的響應,表示為XML,這個(gè)對象可以解析為一個(gè)DOM對象
status
服務(wù)器的HTTP狀態(tài)
statusText
HTTP狀態(tài)的對應文本
下面我們來(lái)看看這些屬性和事件的詳細說(shuō)明。
1. readyState屬性
當XMLHttpRequest對象吧一個(gè)HTTP請求發(fā)送到服務(wù)器時(shí)將經(jīng)歷若干種狀態(tài)。一直等待直到請求被處理,然后,它才接收一個(gè)響應。這樣以來(lái),腳本才正確響應各種狀態(tài),XMLHttpRequest對象暴露一個(gè)描述對象的當前狀態(tài)的readyState屬性,如下表所示:
readyState取值
描述
0
描述一種“未初始化”狀態(tài)。此時(shí),已經(jīng)創(chuàng )建了一個(gè)XMLHttpRequest對象,但是還沒(méi)有初始化。
1
描述一種“發(fā)送”狀態(tài)。此時(shí),代碼已經(jīng)調用了XMLHttpRequest open()方法并且XMLHttpRequest已經(jīng)準備好把一個(gè)請求發(fā)送到服務(wù)器。
2
描述一種“發(fā)送”狀態(tài)。此時(shí),已經(jīng)通過(guò)send()方法把一個(gè)請求發(fā)送到服務(wù)器端,但是還沒(méi)有收到一個(gè)響應。
3
描述一種“正在接收”狀態(tài)。此時(shí),已經(jīng)接收到HTTP響應頭部信息,但是消息體部分還沒(méi)有完全接收結束。
4
描述一種“已加載”狀態(tài)。此時(shí),響應已經(jīng)被完全接收。
2. onreadystatechange屬性
無(wú)論readyState值何時(shí)發(fā)生改變,XMLHttpRequest對象都會(huì )激發(fā)一個(gè)readystatechange事件。其中,onreadystatechange屬性接收一個(gè)EventListener值,向該方法指示無(wú)論readyState值何時(shí)發(fā)生改變,該對象都將激活。
3. responseText屬性
這個(gè)responseText屬性包含客戶(hù)端接收到的HTTP響應的文本內容。當readyState值為0、1或2時(shí),responseText包含一個(gè)空字符串。當readyState值為3(正在接收)時(shí),響應中包含客戶(hù)端還未完成的響應信息。當readyState為4(已加載)時(shí),該responseText包含完整的響應信息。
4. responseXML屬性
此屬性用于當接收到完整的HTTP響應時(shí)(readyState為4)描述XML響應;此時(shí),Content-Type頭部指定MIME(媒體)類(lèi)型為text/xml,application/xml或以+xml結尾。如果Content-Type頭部并不包含這些媒體類(lèi)型之一,那么responseXML的值為null。無(wú)論何時(shí),只要readyState值不為4,那么該responseXML的值也為null。
其實(shí),這個(gè)responseXML屬性值是一個(gè)文檔接口類(lèi)型的對象,用來(lái)描述被分析的文檔。如果文檔不能被分析(例如,如果文檔不是良構的或不支持文檔相應的字符編碼),那么responseXML的值將為null。
5. status屬性
這個(gè)屬性描述了HTTP狀態(tài)代碼,而且其類(lèi)型為short。而且,僅當readyState值為3(正在接收中)或4(已加載)時(shí),這個(gè)status屬性才可用。當readyState的值小于3時(shí)試圖存取status的值將引發(fā)一個(gè)異常。例如:status等于200表示成功,404表示未找到資源。
6. statusText屬性
這個(gè)屬性描述了HTTP狀態(tài)代碼文本,并且僅當readyState值為3或4才可用。當readyState為其它值時(shí)試圖存取statusText屬性將引發(fā)一個(gè)異常。
XMLHttpRequest對象的方法
下表顯示了XMLHttpRequest對象的一些常用的方法,其中描述部分介紹了這些方法的作用和意義。
方法
描述
abort()
停止當前請求
getAllResponseHeaders()
把HTTP請求的所有相應首部作為鍵/值對返回。
getResponseHeader("header")
返回指定首部的串值。
open("method","url")
建立對服務(wù)器的調用。method參數可以是GET、POST或PUT等;url參數可以是相對URL或絕對URL。這個(gè)方法還包括3個(gè)可選參數。
send(content)
向服務(wù)器發(fā)送請求。
setRequestHeader("header","value")
把指定首部設置為所提供的值,在設置任何首部之前必須先調用open()方法。
下面我們來(lái)更詳細的看看這些方法的使用。
1. abort()方法
可以使用這個(gè)abort()方法來(lái)暫停與一個(gè)XMLHttpRequest對象相聯(lián)系的HTTP請求,從而把該對象復位到未初始化狀態(tài)。
2. open()方法
此方法用來(lái)和服務(wù)器之間建立連接。其完整的方法參數是open(string method,string uri,boolean asynch,string username,string password),其中前兩個(gè)參數是必要的,后面三個(gè)為可選參數。
method參數是必須提供的,用于指定用來(lái)發(fā)送請求的HTTP方法(GET,POST,PUT,DELETE或HEAD)。為了把數據發(fā)送到服務(wù)器,應該使用POST方法;為了從服務(wù)器端檢索數據,應該使用GET方法。另外,uri參數用于指定XMLHttpRequest對象把請求發(fā)送到的服務(wù)器相應的URI。借助于