我要說的內容都是非常基礎的內容,高手就免看了,如果看了歡迎給點意見啊。新手或對低層還不是很了解的人可以看看,幫助理解與記憶。
XMLHttpRequest 物件是AJAX功能的核心,要開發AJAX程式必須從了解XMLHttpRequest 物件開始。
了解XMLHttpRequest 物件就先從建立XMLHttpRequest 物件開始,在不同的瀏覽器中建立XMLHttpRequest 物件使用不同的方法:
先看看IE建立XMLHttpRequest 物件的方法(方法1): var xmlhttp = new ActiveXObject("MsxmlRequest 物件的方法(方法1): var xmlhttp = new ActiveXObject("MsxmlRequest 物件的方法(方法1): var xmlhttp = new ActiveXObject("MsxmlRequest 物件的方法(方法1):
var xmlhttp = new ActiveXObject("MsxmlRequest 物件的方法(方法1) ); //使用較新版本的IE 建立IE 相容的物件(Msxml2.XMLHTTP)
var xmlhttp = new ActiveXObject("Microsoft.XMLHTTP"); //使用較舊版本的IE 建立IE 相容的物件(Microsoft.XMLHTTP)
而Mozilla、Opera、Safari 和大部分非IE的瀏覽器都使用下面這種方法(方法2)來建立XMLHttpRequest 物件:
var xmlhttp = new XMLHttpRequest();
實際上Internet Explorer 使用了一個名為XMLHttp 的對象,而不是XMLHttpRequest 對象,而Mozilla、Opera、Safari 和大部分非Microsoft 瀏覽器都使用的是後者(下文統稱XMLHttpRequest 對象)。 IE7開始也開始使用XMLHttpRequest 物件了。
在建立XMLHttpRequest 物件的時候如果不同的瀏覽器使用了不正確的方法瀏覽器都會報錯,並且無法使用該物件。所以我們需要一個可以相容於不同瀏覽器的建立XMLHttpRequest 物件的方法:
建立相容多瀏覽器的XMLHttpRequest 物件方法
var xmlhttp = false; //建立一個新變數request 並賦值false。使用false 作為判斷條件,它表示還沒有建立XMLHttpRequest 物件。
function CreateXMLHttp(){
try{
xmlhttp = new XMLHttpRequest(); //嘗試建立XMLHttpRequest 對象,除IE 外的瀏覽器都支援這個方法。
}
catch (e){
try{
xmlhttp = new ActiveXObject("Msxml2.XMLHTTP"); //使用較新版本的IE 建立IE 相容的物件(Msxml2.XMLHTTP)
}
catch (e){
try{
xmlhttp = new ActiveXObject("Microsoft.XMLHTTP"); //使用較舊版本的IE 建立IE 相容的物件(Microsoft.XMLHTTP)。
}
catch (failed){
xmlhttp = false; //如果失敗則保證request 的值仍然為false。
}
}
}
return xmlhttp;
}
判斷是否創建成功就很簡單了
if (!xmlhttp){
//建立XMLHttpRequest 物件失敗!
}
else{
//建立成功!
}
創建好了XMLHttpRequest 物件我們再來看看這個物件的方法、屬性以及最重要的onreadystatechange事件句柄吧。
方法:
open() 說明:初始化HTTP 請求參數,例如URL 和HTTP 方法,但不會傳送請求。
abort() 說明:取消目前回應,關閉連線並且結束任何未決的網路活動。
getAllResponseHeaders() 說明:把HTTP 回應頭部當作未解析的字串回傳。
getResponseHeader() 說明:傳回指定的HTTP 回應頭部的值。
send() 說明:傳送HTTP 請求,使用傳遞給open() 方法的參數,以及傳遞給該方法的選用請求體。
setRequestHeader() 說明:向一個開啟但未發送的請求設定或新增一個HTTP 請求。
屬性:
readyState 說明:HTTP 請求的狀態。
responseText 說明:目前為止為伺服器接收到的回應體(不包括頭部),或者如果還沒接收到資料的話,就是空字串。
responseXML 說明:對請求的回應,解析為XML 並以Document 物件傳回。
status 說明:由伺服器傳回的HTTP 狀態代碼。
statusText 說明:這個屬性用名稱而不是數字指定了請求的HTTP 的狀態碼。
onreadystatechange 是每次readyState 屬性改變的時候調用的事件句柄函數。
下面就從發送請求並處理請求結果的過程來理解XMLHttpRequest 物件吧。
發送請求之前自然就是產生一個XMLHttpRequest 對象,程式碼上面有了就不多寫了。
產生一個XMLHttpRequest 物件
var xmlhttp = CreateXMLHttp();
創建好XMLHttpRequest 物件了,那我們要送請求到哪個網站呢,就選擇博客園首頁的RSS吧。那要怎麼設定我要請求的網站位址呢,使用open()方法。
open(method, url, async, username, password)
方法有5個參數,具體什麼意思可以看這裡: http://www.w3school.com.cn/xmldom/dom_http.asp
我們用的就是這個了。
xmlHttp.open("get"," http://www.cnblogs.com",true );
get參數表示用get方法,第二個自然就是目標位址,部落格園首頁,第三個就是表示是否異步了,我們當然使用true了。具體的參數說明都可以到http://www.w3school.com.cn上面看了。
好了,目標定好了,要怎麼發送。用send()方法。
send(body),send()方法只有一個參數,表示DOM對象,這個DOM對象需要說明的內容很多,下次說,今天我們只要寫
xmlhttp.send(null);
就可以了。好了,發送了,那怎麼處理回傳的結果呢,這時候就用到XMLHttpRequest 物件最重要的東西了,那就是onreadystatechange事件句柄。什麼意思呢,那就需要說明XMLHttpRequest 物件的readyState了,readyState有5種狀態,分別用數字的0 到4 來表示。
狀態 名稱 描述
0 Uninitialized 初始化狀態。 XMLHttpRequest 物件已建立(未呼叫open()之前)或已被abort() 方法重設。
1 Open open() 方法已調用,但是send() 方法未調用。請求還沒有被發送。
2 Sent Send() 方法已調用,HTTP 請求已傳送至Web 伺服器。未接收到響應。
3 Receiving 所有回應頭部都已經接收到。響應體開始接收但未完成。
4 Loaded HTTP 回應已完全接收。
但要注意的是,onreadystatechange事件句柄不同的瀏覽器能處理的狀態並不一致,IE和FireFox能處理1到4,而Safari能處理2到4的狀態,Opera 能處理3、4兩中狀態。 0的狀態基本上沒什麼用,因為創建了XMLHttpRequest 物件後都會馬上呼叫open() 方法,這時候狀態就變成1了,當然除非你要判斷物件是否已經被abort() 取消,可是這樣的情況依然很少。大部分情況下判斷是不是4(已經接受完成)這個狀態就夠了。
好了,明白了readyState有5種狀態了,那處理回傳結果就是看狀態變更到不同的狀態我們做不同的處理就可以了,怎麼告訴XMLHttpRequest 物件狀態變更時讓誰來處理這個變更呢。有兩種寫法,一種是用匿名方法,另一種是指定方法,其實只是不同的寫發,作用都一樣,看下程式碼:
xmlhttp.onReadyStateChange = function (){
//處理狀態變化的程式碼
}
//或者
xmlhttp.onReadyStateChange = getResult;
function getResult(){
///處理狀態變化的程式碼
}
//順便說一下,句柄的名稱比較長,可以這樣記憶on ReadyState Change 表示在讀取狀態改變時請求發送了,也指定處理方法了,怎麼獲取返回的內容呢,有responseText和responseXML兩個屬性可使用,responseXML是回傳對象,需要再解析,後面再說,這裡先用responseText,看看回傳什麼。
alert(xmlhttp.responseText); //看看是不是回傳了首頁的HTML程式碼啊。是你就成功了。
整個過程是:建立XMLHttpRequest 物件-> 指定發送地址及發送方法-> 發送請求-> 指定處理方法並處理回傳結果。但要注意,我們正常的思路理解是這樣的,可是onreadystatechange事件句柄指定處理方法需要在發送之前就指定好,否則無法處理狀態變更事件。
所以我們應該按照下面的流程來記憶:建立XMLHttpRequest 物件-> 指定發送位址及發送方法-> 指定狀態變更處理方法-> 發送請求,請求發送後狀態變更了就會自動呼叫指定的處理方法。
好了,看看完成的程式碼吧。
完成的程式碼
var xmlhttp = false; //建立一個新變數request 並賦值false。使用false 作為判斷條件,它表示還沒有建立XMLHttpRequest 物件。
function CreateXMLHttp(){
try{
xmlhttp = new XMLHttpRequest(); //嘗試建立XMLHttpRequest 對象,除IE 外的瀏覽器都支援這個方法。
}
catch (e){
try{
xmlhttp = new ActiveXObject("Msxml2.XMLHTTP"); //使用較新版本的IE 建立IE 相容的物件(Msxml2.XMLHTTP)
}
catch (e){
try{
xmlhttp = new ActiveXObject("Microsoft.XMLHTTP"); //使用較舊版本的IE 建立IE 相容的物件(Microsoft.XMLHTTP)。
}
catch (failed){
xmlhttp = false; //如果失敗則保證request 的值仍然為false。
}
}
}
return xmlhttp;
}
xmlhttp = CreateXMLHttp();
xmlhttp.open("get"," http://www.cnblogs.com",true );
xmlhttp.onReadyStateChange = getResult;
xmlhttp.send(null);
function getResult(){
if(xmlhttp.readyState == 4){
alert(xmlhttp.responseText);
}
}
看似一切都OK了,可是有沒有想過,如果HTML程式碼在網路傳輸過程中出錯了,或是我們指定的位址失效會怎麼樣呢。這時候就需要用到status屬性,也就是由伺服器傳回的HTTP 狀態碼。 xmlhttp.status 等於200時表示傳輸過程完整沒有錯誤。具體的HTTP狀態碼什麼意思可以到W3C組織網站上看看,網址http://www.w3.org/Protocols/rfc2616/rfc2616-sec6.html#sec6.1.1 。
把getResult()方法寫成下面這樣我覺的就真的OK了。
function getResult(){
if(xmlhttp.readyState == 4 && xmlhttp.status == 200){
alert(xmlhttp.responseText);
}
}
好了,一個本來還蠻簡單的東西,被我寫的這麼多,好像很囉嗦。不過我覺的程式對基礎內容的理解很重要,現在很多時候開發AJAX的程式都使用很多JS的函式庫,不需要直接寫這麼基礎的程式碼。如使用著名的jQuery,但是如果我們對基礎的東西有很好的理解,那麼這些庫報告錯誤,或者出現問題我們可以很好很快的知道錯在哪裡,更快的做出改變使程序正常運行。