標籤:
XMLHttpRequest對象是Ajax技術的核心。在Internet Explorer 5中,XMLHttpRequest對象以ActiveX對象引入,被稱之為XMLHTTP,它是一種支援非同步請求的技術。後來Mozilla、Netscape、Safari、Firefox和其他瀏覽器也提供了XMLHttpRequest類,雖然這些瀏覽器都提供了XMLHttpRequest類,但它們建立XMLHttpRequest類的方法並不相同。XMLHttpRequest使我們可以使用JavaScript向伺服器提出請求並處理響應,而不阻塞使用者的其他動作。
不重新整理頁面就和伺服器進行互動是Ajax最大的特點。這個重要的特點主要歸功於XMLHttpRequest對象。使用XMLHttpRequest對象使得網頁應用程式像windows應用程式一樣,能夠及時響應使用者與伺服器之間的互動,不必進行頁面重新整理或者跳轉,並且能夠進行一系列的資料處理,這些功能可以使使用者的等待時間縮短,同時也減輕了伺服器端的負載。
目前XMLHttpRequest對象已經得到了大部分瀏覽器的支援,因此使用Ajax技術開發Web應用程式的時候一般情況下不會出現問題。不過,當開發人員確定使用Ajax技術來開發時,仍然需要考慮使用者會使用什麼樣的瀏覽器來對網站進行訪問,雖然不支援XMLHttpRequest對象的瀏覽器佔少數。
在使用XMLHttpRequest對象向伺服器發送請求和處理響應之前,必修先用JavaScript建立一個XMLHttpRequest對象,然後通過這個對象來和伺服器建立請求並接收伺服器返回的資料。由於XMLHttpRequest不是一個W3C標準,所以可以採用多種方法使用JavaScript來建立XMLHttpRequest的執行個體。Internet Explorer把XMLHttpRequest實現為一個ActiveX對象,其他瀏覽器(如Firefox、Safari和Opera等)把它實現為一個本地JavaScript對象。由於存在這些差別,JavaScript代碼中必須包含有關的邏輯,從而使用ActiveX技術或者使用本地JavaScript對象技術來建立XMLHttpRequest的一個執行個體。
正因為在不同的瀏覽器中,XMLHttpRequest對象的建立方式不同,因此在程式中建立XMLHttpRequest對象之前需要對瀏覽器進行判斷。使用詳細編寫代碼方式來區別瀏覽器類型的方式不僅代碼量大,而且很不方便也不靈活。在這裡我們可以換一種思路來解決,只需要檢查瀏覽器是否提供對ActiveX對象的支援即可。如果瀏覽器支援ActiveX對象,就可以使用ActiveX來建立XMLHttpRequest對象。否則,就需要在程式中使用本地JavaScript對象技術來建立。下面的代碼展示了在不同的瀏覽器中使用JavaScript代碼來建立XMLHttpRequest對象的編程方法。
function createXMLHttpRequest() { var xmlreq = false; if (window.ActiveXObject) { xmlreq = new ActiveXObject("Microsoft.XMLHTTP"); } else if (window.XMLHttpRequest) { xmlreq = new XMLHttpRequest(); } return xmlreq; }
我們從上面代碼中看出,建立XMLHttpRequest對象的過程比較簡單。首先在createXMLHttpRequest()方法中建立了一個變數xmlreq來儲存對這個對象的引用,並將其預設值設定為false。然後在這個方法中通過簡單的判斷,確定究竟使用什麼方法來建立對象。由於使用者使用的瀏覽器類型不同,代碼window.ActiveXObject可能返回一個對象,也可能返回null。If條件陳述式根據返回的結果來判斷瀏覽器是否能支援ActiveX控制項,相應地得知瀏覽器是IE還是其他瀏覽器類型。如果判定使用者使用的是IE瀏覽器,則通過執行個體化ActiveXObject的一個執行個體的方法來建立XMLHttpRequest對象。使用這種方法時,參數字串指明要建立何種類型的ActiveX對象。在本例子中,參數是Microsoft.XMLHTTP,這說明需要建立的是XMLHttpRequest的一個執行個體。
如果window.ActiveXObject返回null,表示使用者使用的瀏覽器不支援ActiveX對象,那麼程式會執行else語句所指定的操作。首先判斷瀏覽器是否把XMLHttpRequest實現為本地JavaScript對象。如果存在window.XMLHttpRequest,那麼就建立XMLHttpRequest對象。最後將這個xmlreq變數返回,完成了XMLHttpRequest對象的建立過程。
由於JavaScript具有動態類型的特性,而且XMLHttpRequest對象在不同瀏覽器上的實現是相容的,所有可以用同樣的方式訪問XMLHttpRequest執行個體的屬性和方法,而不論這個執行個體建立的方法是什麼。這就大大簡化了開發過程,而且在JavaScript中也不必編寫特定於瀏覽器的邏輯。
XMLHttpRequest對象的屬性
XMLHttpRequest對象提供了許多屬性,處理XMLHttpRequest時需要頻繁用到這些屬性,如下表所示:
屬性 |
描述 |
onreadystatechange |
每個狀態改變時都會觸發這個事件處理常式,通常會調用一個JavaScript函數 |
readyState |
請求的狀態 |
responseText |
伺服器的響應,表示為一個串 |
responseXML |
伺服器的響應,表示為XML,這個對象可以解析為一個DOM對象 |
status |
伺服器的HTTP狀態 |
statusText |
HTTP狀態的對應文本 |
下面我們來看看這些屬性和事件的詳細說明。
1. readyState屬性
當XMLHttpRequest對象吧一個HTTP請求發送到伺服器時將經曆若干種狀態。一直等待直到請求被處理,然後,它才接收一個響應。這樣以來,指令碼才正確響應各種狀態,XMLHttpRequest對象暴露一個描述對象的目前狀態的readyState屬性,如下表所示:
readyState取值 |
描述 |
0 |
描述一種“未初始化”狀態。此時,已經建立了一個XMLHttpRequest對象,但是還沒有初始化。 |
1 |
描述一種“發送”狀態。此時,代碼已經調用了XMLHttpRequest open()方法並且XMLHttpRequest已經準備好把一個請求發送到伺服器。 |
2 |
描述一種“發送”狀態。此時,已經通過send()方法把一個請求發送到伺服器端,但是還沒有收到一個響應。 |
3 |
描述一種“正在接收”狀態。此時,已經接收到HTTP回應標頭部資訊,但是訊息體部分還沒有完全接收結束。 |
4 |
描述一種“已載入”狀態。此時,響應已經被完全接收。 |
2. onreadystatechange屬性
無論readyState值何時發生改變,XMLHttpRequest對象都會激發一個readystatechange事件。其中,onreadystatechange屬性接收一個EventListener值,向該方法指示無論readyState值何時發生改變,該對象都將啟用。
3. responseText屬性
這個responseText屬性包含用戶端接收到的HTTP響應的常值內容。當readyState值為0、1或2時,responseText包含一個Null 字元串。當readyState值為3(正在接收)時,響應中包含用戶端還未完成的響應資訊。當readyState為4(已載入)時,該responseText包含完整的響應資訊。
4. responseXML屬性
此屬性用於當接收到完整的HTTP響應時(readyState為4)描述XML響應;此時,Content-Type頭部指定MIME(媒體)類型為text/xml,application/xml或以+xml結尾。如果Content-Type頭部並不包含這些媒體類型之一,那麼responseXML的值為null。無論何時,只要readyState值不為4,那麼該responseXML的值也為null。
其實,這個responseXML屬性值是一個文檔介面類型的對象,用來描述被分析的文檔。如果文檔不能被分析(例如,如果文檔不是良構的或不支援文檔相應的字元編碼),那麼responseXML的值將為null。
5. status屬性
這個屬性描述了HTTP狀態碼,而且其類型為short。而且,僅當readyState值為3(正在接收中)或4(已載入)時,這個status屬性才可用。當readyState的值小於3時試圖存取status的值將引發一個異常。例如:status等於200表示成功,404表示未找到資源。
6. statusText屬性
這個屬性描述了HTTP狀態碼文本,並且僅當readyState值為3或4才可用。當readyState為其它值時試圖存取statusText屬性將引發一個異常。
XMLHttpRequest對象的方法
下表顯示了XMLHttpRequest對象的一些常用的方法,其中描述部分介紹了這些方法的作用和意義。
方法 |
描述 |
abort() |
停止當前請求 |
getAllResponseHeaders() |
把HTTP請求的所有相應首部作為鍵/值對返回。 |
getResponseHeader("header") |
返回指定首部的串值。 |
open("method","url") |
建立對伺服器的調用。method參數可以是GET、POST或PUT等;url參數可以是相對URL或絕對URL。這個方法還包括3個選擇性參數。 |
send(content) |
向伺服器發送請求。 |
setRequestHeader("header","value") |
把指定首部設定為所提供的值,在設定任何首部之前必須先調用open()方法。 |
下面我們來更詳細的看看這些方法的使用。
1. abort()方法
可以使用這個abort()方法來暫停與一個XMLHttpRequest對象相聯絡的HTTP請求,從而把該對象複位到未初始化狀態。
2. open()方法
此方法用來和伺服器之間建立串連。其完整的方法參數是open(string method,string uri,boolean asynch,string username,string password),其中前兩個參數是必要的,後面三個為選擇性參數。
method參數是必須提供的,用於指定用來發送請求的HTTP方法(GET,POST,PUT,DELETE或HEAD)。為了把資料發送到伺服器,應該使用POST方法;為了從伺服器端檢索資料,應該使用GET方法。另外,uri參數用於指定XMLHttpRequest對象把請求發送到的伺服器相應的URI。藉助於window.document.baseURI屬性,該uri被解析為一個絕對的URI。換句話說,如果使用相對的URI,它將使用與瀏覽器解析相對的URI一樣的方式被解析。Asynch參數指定是否請求是非同步,預設值為true。為了發送一個同步請求,需要把這個參數設定為false。但Ajax技術的最大優點是 調用,因此如果這個參數設定為false,則將失去使用XMLHttpRequest對象的意義。對於要求認證的伺服器,可以提供可選的使用者名稱和口令參數。在調用open()方法後,XMLHttpRequest對象把它的readyState屬性設定為1(開啟)並且把responseText、responseXML、status和statusText屬性複位到它們的初始值。另外,它還複位要求標頭部。注意,如果調用open()方法並且此時readyState為4,則XMLHttpRequest對象將複位這些值。
3. send()方法
在通過調用open()方法準備好一個請求之後,需要把該請求發送到伺服器。僅當readyState值為1時,才可以調用send()方法。否則的話,XMLHttpRequest對象將引發一個異常。該請求被使用提供給open()方法的參數發送到伺服器。當asynch參數為true時,send()方法立即返回,從而允許其它用戶端指令碼處理繼續。在調用send()方法後,XMLHttpRequest對象把readyState的值設定為2(發送)。當伺服器響應時,在接收訊息體之前,如果存在任何訊息體的話,XMLHttpRequest對象將把readyState設定為3(正在接收中)。當請求完成載入時,它把readyState設定為4(已載入)。對於一個HEAD類型的請求,它將在把readyState值設定為3後再立即把它設定為4。
send()方法使用一個可選的參數,該參數可以包含可變類型的資料。典型地,使用它並通過POST方法把資料發送到伺服器。另外,可以顯式地使用null參數調用send()方法,這與不用參數調用它一樣。對於大多數其它的資料類型,在調用send()方法之前,應該使用setRequestHeader()方法(見後面的解釋)先設定Content-Type頭部。
如果在send(content)方法中的content參數的類型為string,那麼,資料將被編碼為UTF-8。
如果資料是Document類型,那麼將使用由data.xmlEncoding指定的編碼序列化該資料。
注意,由於調用這個方法後就把請求發出去了,所以對於XMLHttpRequest對象的設定需要在調用這個方法之前來完成。另外,對於send()方法中的那個參數,雖然是可選的,但是最好在不需要發送資料的時候也不能省略這個參數,應該將其設定成null,否則將會在Firefox中有錯誤。
4. setRequestHeader("header","value")方法
該方法用來佈建要求的頭部資訊。當readyState值為1時,可以在調用open()方法後調用這個方法。否則,將得到一個異常。
5. getResponseHeader("header")方法
該方法用於檢索響應的頭部值。僅當readyState值是3或4(換句話說,在回應標頭部可用以後)時,才可以調用這個方法;否則,該方法返回一個Null 字元串。
6. getAllResponseHeaders()方法
該方法以一個字串形式返回所有的回應標頭部(每一個頭部占單獨的一行)。如果readyState的值不是3或4,則該方法返回null。
Ajax中的XMLHttpRequest對象詳解