- Ajax與jQuery程序設(shè)計(jì)
- 程永恒
- 3431字
- 2020-06-29 11:32:57
2.2 XMLHttpRequest的方法和屬性
XMLHttpRequest包含了一些基本的屬性和方法,它正是通過(guò)這些屬性和方法與服務(wù)器通信的。Ajax則依賴XMLHttpRequest來(lái)完成與服務(wù)器的通信,XMLHttpRequest是Ajax與服務(wù)器異步通信的核心。
通過(guò)XMLhttpRequest對(duì)象與服務(wù)器的異步通信,可避免每次發(fā)送請(qǐng)求對(duì)應(yīng)一個(gè)頁(yè)面的模式,從而允許在一個(gè)頁(yè)面發(fā)送多次異步請(qǐng)求,每次只從服務(wù)器讀取必需的信息。通過(guò)使用Ajax既可以減輕服務(wù)器的負(fù)擔(dān),又可以加快響應(yīng)速度、縮短用戶等待時(shí)間。
2.2.1 XMLHttpRequest的方法
XMLHttpRequest對(duì)象的方法并不多,下面是基本方法。
(1)abort():取消當(dāng)前響應(yīng),關(guān)閉連接并且結(jié)束任何未決的網(wǎng)絡(luò)活動(dòng)。
這個(gè)方法把XMLHttpRequest對(duì)象重置為readyState為0的狀態(tài),并且取消所有未決的網(wǎng)絡(luò)活動(dòng)。例如,如果請(qǐng)求用了太長(zhǎng)時(shí)間,而且響應(yīng)不再必要,則可以調(diào)用這個(gè)方法。
(2)getAllResponseHeaders():把HTTP響應(yīng)頭部作為未解析的字符串返回。
如果readyState小于3,這個(gè)方法返回null;否則,它返回服務(wù)器發(fā)送的所有HTTP響應(yīng)的頭部。頭部作為單個(gè)的字符串返回,一行一個(gè)頭部,每行用換行符"\r\n"隔開。
(3)getResponseHeader():返回指定的HTTP響應(yīng)頭部的值。其參數(shù)是要返回的HTTP響應(yīng)頭部的名稱。可以使用任何大小寫字母指定這個(gè)頭部的名字,和響應(yīng)頭部的比較是不區(qū)分大小寫的。該方法的返回值是指定的HTTP響應(yīng)頭部的值,如果沒有接收到這個(gè)頭部或者readyState小于3,則為空字符串;如果接收到多個(gè)有指定名稱的頭部,則這個(gè)頭部的值被連接起來(lái)并返回,使用逗號(hào)和空格分隔開各個(gè)頭部的值。
(4)open("method","URL" [,asyncFLag[,"userName" [,"password"]]]):初始化HTTP請(qǐng)求參數(shù),如URL和HTTP方法,但是并不發(fā)送請(qǐng)求。
(5)send(content):發(fā)送HTTP請(qǐng)求,使用傳遞給open()方法的參數(shù),以及傳遞給該方法的可選請(qǐng)求體。
(6)setRequestHeader("label","value"):向一個(gè)打開但未發(fā)送的請(qǐng)求設(shè)置或添加一個(gè)HTTP請(qǐng)求。
下面依次介紹這些常用方法的具體用法。
在請(qǐng)求被發(fā)送之后,getAllResponseHeaders和getResponseHeader這兩個(gè)方法可用于獲取服務(wù)器響應(yīng)頭。
雖然getAllResponseHeaders方法用于返回全部的響應(yīng)頭,但其返回值并不是一個(gè)數(shù)組,也不是一個(gè)對(duì)象,而是一個(gè)字符串——由所有響應(yīng)頭的“名:值”對(duì)所組成的字符串,即如下形式:

具體的響應(yīng)頭數(shù)目取決于生成響應(yīng)的程序設(shè)置了多少。如下面的HTML頁(yè)面所示,該頁(yè)面向服務(wù)器異步發(fā)送請(qǐng)求,處理響應(yīng)時(shí)將所有的響應(yīng)頭全部輸出。


上面的代碼中粗體字代碼指定當(dāng)下拉列表框中的所選項(xiàng)發(fā)送改變時(shí)將會(huì)觸發(fā)change()函數(shù),該函數(shù)會(huì)向服務(wù)器second.jsp頁(yè)面發(fā)送異步請(qǐng)求。系統(tǒng)采用POST方法發(fā)送請(qǐng)求,請(qǐng)求得到響應(yīng)后,使用getAllResponseHeaders()方法獲得所有的請(qǐng)求頭,并將請(qǐng)求頭以警告框和頁(yè)面輸出兩種方式輸出。
上面的頁(yè)面是級(jí)聯(lián)下拉列表的實(shí)例。當(dāng)選擇不同國(guó)家時(shí),該國(guó)家對(duì)應(yīng)的城市將在下面顯示,該應(yīng)用的second.jsp頁(yè)面的代碼如下:

上面的頁(yè)面只是一個(gè)簡(jiǎn)單的JSP頁(yè)面,該頁(yè)面將會(huì)對(duì)客戶端異步請(qǐng)求生成響應(yīng)。客戶端獲取服務(wù)器響應(yīng)時(shí),并未處理響應(yīng)數(shù)據(jù),而是獲取了響應(yīng)頭。響應(yīng)頭通過(guò)兩種方式輸出:一種是通過(guò)警告對(duì)話框,另一種是通過(guò)頁(yè)面<div…/>元素加載。
在瀏覽器中瀏覽該頁(yè)面,并改變下拉列表框里的選中選項(xiàng),將彈出如圖2-1所示的警告框。該框的第一行是所獲取響應(yīng)頭的類型,后面各行是所有響應(yīng)頭以及對(duì)應(yīng)的值。
上面的程序發(fā)送請(qǐng)求時(shí)調(diào)用了setRequestHeader()方法設(shè)置請(qǐng)求頭。因?yàn)樵诎l(fā)送POST請(qǐng)求時(shí)應(yīng)設(shè)置對(duì)應(yīng)的編碼方式。XMLHttpRequest提供的open()和send()方法主要用于發(fā)送請(qǐng)求。
在調(diào)試Ajax應(yīng)用時(shí),不能只調(diào)試HTML頁(yè)面的JavaScript腳本,對(duì)服務(wù)器響應(yīng)卻不甚理會(huì)。實(shí)際上,在調(diào)試JavaScript腳本之前,應(yīng)該先保證服務(wù)器響應(yīng)正確,例如,此處直接請(qǐng)求服務(wù)器的second.jsp頁(yè)面,將可看到如圖2-2所示的頁(yè)面。

圖2-1 警告框

圖2-2 服務(wù)器響應(yīng)正確
2.2.2 XMLHttpRequest的屬性
XMLHttpRequest的屬性也很簡(jiǎn)單,Ajax技術(shù)通過(guò)XMLHttpRequest的這些簡(jiǎn)單屬性實(shí)現(xiàn)與服務(wù)器的異步通信。
XMLHttpRequest對(duì)象常用的屬性如下:
(1)onreadystatechange:該屬性用于指定XMLHttpRequest對(duì)象狀態(tài)改變時(shí)的事件處理函數(shù)。
(2)readyState:該屬性用于獲取XMLHttpRequest對(duì)象的處理狀態(tài)。
(3)responseText:該屬性用于獲取服務(wù)器的響應(yīng)文本。
(4)responseXML:該屬性用于獲取服務(wù)器響應(yīng)的XML文檔對(duì)象。
(5)status:該屬性是服務(wù)器返回的狀態(tài)碼,只有當(dāng)服務(wù)器的響應(yīng)已經(jīng)完成時(shí),才會(huì)有該狀態(tài)碼。
(6)statusText:該屬性是服務(wù)器返回的狀態(tài)文本信息,只有當(dāng)服務(wù)器的響應(yīng)已經(jīng)完成時(shí),才會(huì)有該狀態(tài)文本信息。
1.onreadystatechange和readyState屬性
onreadystatechange屬性用于指定XMLHttpRequest對(duì)象的狀態(tài)改變函數(shù)。當(dāng)XMLHttpRequest對(duì)象的狀態(tài)改變時(shí),該函數(shù)將被觸發(fā)。
XMLHttpRequest對(duì)象有如下幾種狀態(tài)。
0:XMLHttpRequest對(duì)象還沒有完成初始化。
1:XMLHttpRequest對(duì)象開始發(fā)生請(qǐng)求。
2:XMLhttpRequest對(duì)象的請(qǐng)求發(fā)送完成。
3:XMLHttpRequest對(duì)象開始讀取服務(wù)器的響應(yīng)。
4:XMLHttpRequest對(duì)象讀取服務(wù)器的響應(yīng)結(jié)束。
XMLHttpRequest對(duì)象的這幾種狀態(tài)信息可通過(guò)readyState屬性讀取。因此可以這樣理解:每當(dāng)XMLHttpRequest對(duì)象的readyState屬性改變時(shí),其onreadystatechange屬性指定的方法都會(huì)被觸發(fā)。
修改2.2.1節(jié)示例,將該示例中的first.html頁(yè)面代碼改成如下形式。


從上面的事件處理函數(shù)的代碼可以看出,該函數(shù)僅用來(lái)監(jiān)控XMLHttpRequest對(duì)象的readyState屬性值的改變,當(dāng)該屬性值發(fā)送改變時(shí),該函數(shù)輸出readyState屬性值。
該應(yīng)用的second.jsp頁(yè)面沒有任何修改。
瀏覽該應(yīng)用的first.html頁(yè)面,然后改變其下拉列表中的選項(xiàng),可看到依次彈出一系列的警告對(duì)話框。當(dāng)彈出如圖2-3所示對(duì)話框后,可看到服務(wù)器的控制臺(tái)輸出一個(gè)數(shù)字,該數(shù)字就是所選擇國(guó)家的編號(hào)(second.jsp頁(yè)面的System.out.println(id);代碼輸出該編號(hào))。
服務(wù)器的控制臺(tái)輸出了請(qǐng)求參數(shù),這表明當(dāng)readyState狀態(tài)為2時(shí),服務(wù)器可以獲取到XMLHttpRequest發(fā)送的請(qǐng)求參數(shù)。也就是說(shuō),readyState狀態(tài)為2標(biāo)志著XMLHttpRequest的請(qǐng)求發(fā)送完成。單擊如圖2-3所示對(duì)話框中的“確定”按鈕,還會(huì)依次彈出3、4兩個(gè)對(duì)話框。當(dāng)單擊了4對(duì)話框中的“確定”按鈕后,不會(huì)彈出任何對(duì)話框。此時(shí),服務(wù)器的響應(yīng)已經(jīng)完成。
2.status和statusText屬性
服務(wù)器的響應(yīng)完成后,依然不能直接獲取服務(wù)器響應(yīng)。因?yàn)榉?wù)器響應(yīng)也有很多種情況,如圖2-4所示為常見提示頁(yè)面。

圖2-3 XMLHttpRequest對(duì)象的readyState

圖2-4 系統(tǒng)錯(cuò)誤提示頁(yè)
圖2-4是使用瀏覽器訪問(wèn)一個(gè)并不存在的資源時(shí)服務(wù)器自動(dòng)生成的錯(cuò)誤提示頁(yè)。圖2-4所示的頁(yè)面上有HTTP Status 404字符串,表明服務(wù)器響應(yīng)的狀態(tài)碼為404。404表示資源不存在。即使資源不存在,服務(wù)器一樣會(huì)生成響應(yīng)。也就是說(shuō),即使程序判斷XMLHttpRequest的readyState為4,即服務(wù)器響應(yīng)已經(jīng)完成,從服務(wù)器獲取的響應(yīng)信息依然有可能是錯(cuò)誤的。
為了判斷服務(wù)器的響應(yīng)是否正確,可以檢測(cè)XMLHttpRequest的status或statusText屬性。將上面HTML頁(yè)面的回調(diào)函數(shù)改為如下形式。


上面的回調(diào)函數(shù)表明,當(dāng)服務(wù)器響應(yīng)完成時(shí),將通過(guò)警告對(duì)話框輸出服務(wù)器響應(yīng)的狀態(tài)碼和狀態(tài)提示。為了讓服務(wù)器響應(yīng)生成錯(cuò)誤信息,將second.jsp頁(yè)面修改成如下形式,該頁(yè)面中的粗體字代碼將引發(fā)空指針異常。

再次在瀏覽器中瀏覽first.html頁(yè)面,并改變下拉選擇列表的選項(xiàng),從而向服務(wù)器發(fā)送請(qǐng)求,在瀏覽器中可看到如圖2-5所示的對(duì)話框。
如果將服務(wù)器的響應(yīng)頁(yè)面second.jsp改回原來(lái)的形式,服務(wù)器即可生成正常響應(yīng)。在瀏覽器中發(fā)送請(qǐng)求,將可看到如圖2-6所示的警告框。

圖2-5 服務(wù)器內(nèi)部錯(cuò)誤的status和statusText

圖2-6 服務(wù)器正常響應(yīng)的status和statusText
通過(guò)檢測(cè)XMLHttpRequest對(duì)象的status和statusText屬性,即可判斷服務(wù)器的響應(yīng)是否正常。當(dāng)服務(wù)器的響應(yīng)正常時(shí),JavaScript才應(yīng)該讀取服務(wù)器響應(yīng)信息,并將響應(yīng)信息動(dòng)態(tài)加載到目標(biāo)頁(yè)面。服務(wù)器常用的狀態(tài)碼及其對(duì)應(yīng)的含義如下:
(1)200:請(qǐng)求已成功,請(qǐng)求所希望的響應(yīng)頭或數(shù)據(jù)體將隨此響應(yīng)返回。
(2)304:如果客戶端發(fā)送了一個(gè)帶條件的GET請(qǐng)求且該請(qǐng)求已被允許,而文檔的內(nèi)容(自上次訪問(wèn)以來(lái)或者根據(jù)請(qǐng)求的條件)并沒有改變,則服務(wù)器應(yīng)當(dāng)返回這個(gè)狀態(tài)碼。
(3)400:①語(yǔ)義有誤,當(dāng)前請(qǐng)求無(wú)法被服務(wù)器理解,除非進(jìn)行修改,否則客戶端不應(yīng)該重復(fù)提交這個(gè)請(qǐng)求;②請(qǐng)求參數(shù)有誤。
(4)403:服務(wù)器已經(jīng)理解請(qǐng)求,但是拒絕執(zhí)行它。與401響應(yīng)不同的是,身份驗(yàn)證并不能提供任何幫助,而且這個(gè)請(qǐng)求也不應(yīng)該被重復(fù)提交。如果這不是一個(gè)HEAD請(qǐng)求,而且服務(wù)器希望能夠講清楚為何請(qǐng)求不能被執(zhí)行,那么就應(yīng)該在實(shí)體內(nèi)描述拒絕的原因。當(dāng)然,假如它不希望讓客戶端獲得任何信息,服務(wù)器也可以返回一個(gè)404響應(yīng)。
(5)404:請(qǐng)求失敗,請(qǐng)求所希望得到的資源未在服務(wù)器上被發(fā)現(xiàn)。沒有信息能夠告訴用戶這個(gè)狀況到底是暫時(shí)的還是永久的。
(6)405:請(qǐng)求行中指定的請(qǐng)求方法不能被用于請(qǐng)求相應(yīng)的資源。該響應(yīng)必須返回一個(gè)Allow頭信息,用以表示出當(dāng)前資源能夠接受的請(qǐng)求方法的列表。
(7)407:與401響應(yīng)類似,只不過(guò)客戶端必須在代理服務(wù)器上進(jìn)行身份驗(yàn)證。
(8)414:請(qǐng)求的URI長(zhǎng)度超過(guò)了服務(wù)器能夠解釋的長(zhǎng)度,因此服務(wù)器拒絕對(duì)該請(qǐng)求提供服務(wù)。
(9)500:服務(wù)器遇到了一個(gè)未曾預(yù)料的狀況,導(dǎo)致它無(wú)法完成對(duì)請(qǐng)求的處理。一般來(lái)說(shuō),這個(gè)問(wèn)題都會(huì)在服務(wù)器的程序碼出錯(cuò)時(shí)出現(xiàn)。
通過(guò)上面的介紹可以得到一個(gè)結(jié)論:如果想通過(guò)JavaScript獲取服務(wù)器響應(yīng),必須先判斷服務(wù)器響應(yīng)是否完成。要判斷服務(wù)器的響應(yīng)是否完成,只需判斷XMLHttpRequest對(duì)象的readyState屬性即可。當(dāng)readyState值為4時(shí),代表響應(yīng)完成。服務(wù)器響應(yīng)完成后,還應(yīng)判斷服務(wù)器響應(yīng)是否正確。要判斷服務(wù)器響應(yīng)是否正確,可通過(guò)XMLHttpRequest對(duì)象的status屬性進(jìn)行。當(dāng)status值為200時(shí),服務(wù)器響應(yīng)正確,否則響應(yīng)不正常。
- Go Web編程
- LabVIEW2018中文版 虛擬儀器程序設(shè)計(jì)自學(xué)手冊(cè)
- Python數(shù)據(jù)可視化:基于Bokeh的可視化繪圖
- 算法零基礎(chǔ)一本通(Python版)
- 深入淺出PostgreSQL
- 自制編程語(yǔ)言
- Python忍者秘籍
- Raspberry Pi Robotic Blueprints
- Emotional Intelligence for IT Professionals
- Arduino電子設(shè)計(jì)實(shí)戰(zhàn)指南:零基礎(chǔ)篇
- 大數(shù)據(jù)時(shí)代的企業(yè)升級(jí)之道(全3冊(cè))
- Mastering Apache Camel
- 深入淺出 HTTPS:從原理到實(shí)戰(zhàn)
- PHP+MySQL Web應(yīng)用開發(fā)教程
- Less Web Development Cookbook