我要說的內(nèi)容都是非常基礎(chǔ)的內(nèi)容,老手就免看了,如果看了歡迎給點意見啊。新手或者對低層還不是很了解的人可以看看,幫助理解與記憶。
XMLHttpRequest 對象是AJAX功能的核心,要開發(fā)AJAX程序必須從了解XMLHttpRequest 對象開始。
了解XMLHttpRequest 對象就先從建立 XMLHttpRequest 對象開始,在不同的閱讀器中建立 XMLHttpRequest 對象運用不同的要領(lǐng):
先看看IE建立 XMLHttpRequest 對象的要領(lǐng)(要領(lǐng) 1):
var xmlhttp = new ActiveXObject("Msxml2.XMLHTTP"); //運用較新版本的 IE 建立 IE 兼容的對象(Msxml2.XMLHTTP)
var xmlhttp = new ActiveXObject("Microsoft.XMLHTTP"); //運用較老版本的 IE 建立 IE 兼容的對象(Microsoft.XMLHTTP)
而 Mozilla、Opera、Safari 和大部分非IE的閱讀器都運用下面這種要領(lǐng)(要領(lǐng) 2)建立 XMLHttpRequest 對象:
var xmlhttp = new XMLHttpRequest();
實際上Internet Exp lorer 運用了一個名為 XMLHttp 的對象,而不是 XMLHttpRequest 對象,而 Mozilla、Opera、Safari 和 大部分非 Microsoft 閱讀器都運用的是后者(下文統(tǒng)稱 XMLHttpRequest 對象)。IE7開始也開始運用 XMLHttpRequest 對象了。
在建立 XMLHttpRequest 對象的時候如果不同的閱讀器運用了不正確的要領(lǐng)閱讀器都將會報錯,并且不能運用該對象。所以我們須要一種可以兼容不同閱讀器的建立 XMLHttpRequest 對象的要領(lǐng):
建立兼容多閱讀器的 XMLHttpRequest 對象要領(lǐng)
var xmlhttp = false; //建立一個新變量 request 并賦值 false。運用 false 作為判斷條件,它表示還沒有建立 XMLHttpRequest 對象。
function CreateXMLHttp(){
try{
xmlhttp = new XMLHttpRequest(); //嘗試建立 XMLHttpRequest 對象,除 IE 外的閱讀器都支持這個要領(lǐng)。
}
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 對象我們再來看看這個對象的要領(lǐng)、屬性以及最主要的onreadystatechange事件句柄吧。
要領(lǐng):
open() 說明:原始化 HTTP 請求參數(shù),例如 URL 和 HTTP 要領(lǐng),但是并不發(fā)送請求。
abort() 說明:取消當(dāng)前響應(yīng),關(guān)上連接并且結(jié)束任何未決的網(wǎng)絡(luò)活動。
getAllResponseHeaders() 說明:把 HTTP 響應(yīng)頭部作為未分析的字符串返回。
getResponseHeader() 說明:返回指定的 HTTP 響應(yīng)頭部的值。
send() 說明:發(fā)送 HTTP 請求,運用傳遞給 open() 要領(lǐng)的參數(shù),以及傳遞給該要領(lǐng)的可選請求體。
setRequestHeader() 說明:向一個打開但未發(fā)送的請求配置或添加一個 HTTP 請求。
屬性:
readyState 說明:HTTP 請求的狀態(tài)。
responseText 說明:目前為止為服務(wù)器接收到的響應(yīng)體(不包括頭部),或者如果還沒有接收到數(shù)據(jù)的話,就是空字符串。
responseXML 說明:對請求的響應(yīng),分析為 XML 并作為 Document 對象返回。
status 說明:由服務(wù)器返回的 HTTP 狀態(tài)代碼。
statusText 說明:這個屬性用名稱而不是數(shù)字指定了請求的 HTTP 的狀態(tài)代碼。
onreadystatechange 是每次 readyState 屬性改動的時候調(diào)用的事件句柄函數(shù)。
下面從發(fā)送請求并處理請求結(jié)果的流程來理解一下XMLHttpRequest 對象吧。
發(fā)送請求之前自然就是生成一個XMLHttpRequest 對象,代碼上面有了就不多寫了。
生成一個XMLHttpRequest 對象
var xmlhttp = CreateXMLHttp();
建立好XMLHttpRequest 對象了,那我們要送請求到哪個站點呢,就選擇博客園首頁的RSS吧。那如何配置我要請求的站點地址呢,運用 open()要領(lǐng)。
open(method, url, async, username, password)
該要領(lǐng)有5個參數(shù),具體什么意思可以看這里:http://www.w3school.com.cn/xmldom/dom_http.asp
我們用的就是這個了。
xmlHttp.open("get",");
get參數(shù)表示用get要領(lǐng),第二個自然就是目標(biāo)地址,博客園首頁,第三個就是表示能不能異步了,我們當(dāng)然運用 true了。具體的參數(shù)說明還都可以到http://www.w3school.com.cn上面看了。
好了,目標(biāo)定好了,如何發(fā)送呢。用send()要領(lǐng)。
send(body),send()要領(lǐng)只有一個參數(shù),表示DOM對象,這個DOM對象須要說明的內(nèi)容很多,下次說,今天我們只要寫
xmlhttp.send(null);
就可以了。好了,發(fā)送了,那如何處理返回的結(jié)果呢,這個時候就用到XMLHttpRequest 對象最主要的東西了,那就是onreadystatechange事件句柄。什么意思呢,那就須要說明一下XMLHttpRequest 對象的readyState了,readyState有5種狀態(tài),分別用數(shù)字的 0 到 4 來表示。
狀態(tài) 名稱 描述
0 Uninitialized 原始化狀態(tài)。XMLHttpRequest 對象已建立(未調(diào)用open()之前)或已被 abort() 要領(lǐng)重置。
1 Open open() 要領(lǐng)已調(diào)用,但是 send() 要領(lǐng)未調(diào)用。請求還沒有被發(fā)送。
2 Sent Send() 要領(lǐng)已調(diào)用,HTTP 請求已發(fā)送到 Web 服務(wù)器。未接收到響應(yīng)。
3 Receiving 所有響應(yīng)頭部都已經(jīng)接收到。響應(yīng)體開始接收但未完成。
4 Loaded HTTP 響應(yīng)已經(jīng)完全接收。
但是須要留心的是,onreadystatechange事件句柄不同的閱讀器能處理的狀態(tài)并不一致,IE和FireFox能處理1到4,而Safari能處理2到4的狀態(tài),Opera 能處理3、4兩中狀態(tài)。0的狀態(tài)基本沒什么用,因為建立了XMLHttpRequest 對象后都會馬上調(diào)用open() 要領(lǐng),這時候狀態(tài)就變成1了,當(dāng)然除非你要判斷對象能不能已經(jīng)被 abort() 取消,可是這樣的情況依然很少。大部分情況下判斷是不是4(已經(jīng)接受完成)這個狀態(tài)就夠了。
好了,明白了readyState有5種狀態(tài)了,那處理返回結(jié)果就是看狀態(tài)變更到不同的狀態(tài)我們做不同的處理就可以了,如何告訴XMLHttpRequest 對象狀態(tài)變化時讓誰來處理這個變化呢。有兩種寫法,一種是用匿名要領(lǐng),另一種是指定要領(lǐng),其實只是不同的寫發(fā),作用都一樣,看下代碼:
xmlhttp.onReadyStateChange = function (){
//處理狀態(tài)變化的代碼
}
//或者
xmlhttp.onReadyStateChange = getResult;
function getResult(){
///處理狀態(tài)變化的代碼
}
//順便說一下,句柄的名稱比較長,可以這樣記憶 on ReadyState Change 表示在讀取狀態(tài)改動時
請求發(fā)送了,也指定處理要領(lǐng)了,如何獲取返回的內(nèi)容呢,有responseText和responseXML兩個屬性可供運用,responseXML是返回對象,須要再分析,后面再說,這里先用responseText,看看返回什么。
alert(xmlhttp.responseText); //看看是不是返回了首頁的HTML代碼啊。是你就成功了。
整個流程是:建立 XMLHttpRequest 對象 -> 指定發(fā)送地址及發(fā)送要領(lǐng) -> 發(fā)送請求 -> 指定處理要領(lǐng)并處理返回結(jié)果。但是須要留心,我們正常的思路理解是這樣的,可是onreadystatechange事件句柄指定處理要領(lǐng)須要在發(fā)送之前就指定好,否則不能處理狀態(tài)變化事件。
所以我們應(yīng)該按照下面的流程來記憶:建立 XMLHttpRequest 對象 -> 指定發(fā)送地址及發(fā)送要領(lǐng) -> 指定狀態(tài)變化處理要領(lǐng) -> 發(fā)送請求,請求發(fā)送后狀態(tài)變化了就會自動調(diào)用指定的處理要領(lǐng)。
好了,看看完成的代碼吧。
完成的代碼
var xmlhttp = false; //建立一個新變量 request 并賦值 false。運用 false 作為判斷條件,它表示還沒有建立 XMLHttpRequest 對象。
function CreateXMLHttp(){
try{
xmlhttp = new XMLHttpRequest(); //嘗試建立 XMLHttpRequest 對象,除 IE 外的閱讀器都支持這個要領(lǐng)。
}
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",");
xmlhttp.onReadyStateChange = getResult;
xmlhttp.send(null);
function getResult(){
if(xmlhttp.readyState == 4){
alert(xmlhttp.responseText);
}
}
看似一切都OK了,可是有沒有想過,如果HTML代碼在網(wǎng)絡(luò)傳輸流程中出錯了,或者我們指定的地址失效會如何樣呢。這個時候就須要用到status屬性,即由服務(wù)器返回的 HTTP 狀態(tài)代碼。 xmlhttp.status 等于200時表示傳輸流程完整沒有不正確。具體的HTTP狀態(tài)代碼什么意思可以到W3C組織站點上看看,地址http://www.w3.org/Protocols/rfc2616/rfc2616-sec6.html#sec6.1.1 。
把getResult()要領(lǐng)寫成下面這樣我覺的就真的OK了。
function getResult(){
if(xmlhttp.readyState == 4 && xmlhttp.status == 200){
alert(xmlhttp.responseText);
}
}
好了,一個本來挺基本的東西,被我寫的這么多,好象很羅嗦。不過我覺的編程對基礎(chǔ)內(nèi)容的理解很主要,現(xiàn)在很多時候開發(fā)AJAX的程序都運用很多JS的庫,不須要直接編寫這么基礎(chǔ)的代碼。如運用著名的jQuery,但是如果我們對基礎(chǔ)的東西有很好的理解,那這些庫報告不正確 ,或者出現(xiàn)疑問我們可以很好很快的知道錯在哪里,更快的做出改動使程序正常運行。