calvin-207 |
|
|||
日歷
統(tǒng)計
導航留言簿文章檔案搜索最新評論
|
天氣轉(zhuǎn)涼了!
今天無意中聽到寧財神老師說:如果丈母娘覺得他不適合的時候,通常是經(jīng)濟不夠穩(wěn)定,或者性感太不靠譜,如果遇到親人的阻撓的話,建議放棄。。聽了這段話,我對后面的結(jié)果其實不怎么意外,因為我堅信我要成為一個有穩(wěn)定經(jīng)濟的人,我會為了她一直努力! 今天來談?wù)務(wù)剬jax的理解。Asynchronous JavaScript and Xml (異步的javaScript和Xml) 傳統(tǒng)的web引用是允許用戶端填寫表單(form),當提交表單時就向web服務(wù)器發(fā)送一個請求。服務(wù)器接收并處理傳來的表單,然后送回一個新的頁面,但是這個處理方法太浪費時間了,因為如果遇見重名沖主鍵的時候通常是放不進去,換句話來說這個時候返回來的網(wǎng)頁是一樣的。由于這次應(yīng)用的溝通需要向服務(wù)器發(fā)送請求,應(yīng)用的回應(yīng)時間依賴于服務(wù)器的反應(yīng)時間,這個就導致了用戶界面的 回應(yīng)比本機慢的很多。 在這個的一個前提下,我們提出了Ajax技術(shù)。Ajax應(yīng)用可以僅向服務(wù)器發(fā)送并取回必須的數(shù)據(jù),他使用SOAP或其他一些基礎(chǔ)的XML的頁面服務(wù)接口。并在客戶端采用javaScript處理來自服務(wù)器的回應(yīng)。因為在服務(wù)器和瀏覽器之間的交換數(shù)據(jù)的大量堅守。結(jié)果我們感覺服務(wù)器的回應(yīng)速度更快。很多處理工作可以在發(fā)出請求的客戶端機器上完成,因為帶來的web服務(wù)器的負荷也減少了。 XMLHttpRequest對象是當今所有AJAX和Web 2.0應(yīng)用程序的技術(shù)基礎(chǔ)。盡管軟件經(jīng)銷商和開源社團現(xiàn)在都在提供各種AJAX框架以進一步簡化XMLHttpRequest對象的使用;但是,我們?nèi)匀缓苡斜匾斫膺@個對象的詳細工作機制。 一、 引言 異步JavaScript與XML(AJAX)是一個專用術(shù)語,用于實現(xiàn)在客戶端腳本與服務(wù)器之間的數(shù)據(jù)交互過程。這一技術(shù)的優(yōu)點在于,它向開發(fā)者提供了一種從Web服務(wù)器檢索數(shù)據(jù)而不必把用戶當前正在觀察的頁面回饋給服務(wù)器。與現(xiàn)代瀏覽器的通過存取瀏覽器DOM結(jié)構(gòu)的編程代碼(JavaScript)動態(tài)地改變被顯示內(nèi)容的支持相配合,AJAX讓開發(fā)者在瀏覽器端更新被顯示的HTML內(nèi)容而不必刷新頁面。換句話說,AJAX可以使基于瀏覽器的應(yīng)用程序更具交互性而且更類似傳統(tǒng)型桌面應(yīng)用程序。 Google的Gmail和Outlook Express就是兩個使用AJAX技術(shù)的我們所熟悉的例子。而且,AJAX可以用于任何客戶端腳本語言中,這包括JavaScript,Jscript和VBScript。 AJAX利用一個構(gòu)建到所有現(xiàn)代瀏覽器內(nèi)部的對象-XMLHttpRequest-來實現(xiàn)發(fā)送和接收HTTP請求與響應(yīng)信息。一個經(jīng)由XMLHttpRequest對象發(fā)送的HTTP請求并不要求頁面中擁有或回寄一個<form>元素。AJAX中的"A"代表了"異步",這意味著XMLHttpRequest對象的send()方法可以立即返回,從而讓Web頁面上的其它HTML/JavaScript繼續(xù)其瀏覽器端處理而由服務(wù)器處理HTTP請求并發(fā)送響應(yīng)。盡管缺省情況下請求是異步進行的,但是,你可以選擇發(fā)送同步請求,這將會暫停其它Web頁面的處理,直到該頁面接收到服務(wù)器的響應(yīng)為止。 微軟在其Internet Explorer(IE) 5中作為一個ActiveX對象形式引入了XMLHttpRequest對象。其他的認識到這一對象重要性的瀏覽器制造商也都紛紛在他們的瀏覽器內(nèi)實現(xiàn)了XMLHttpRequest對象,但是作為一個本地JavaScript對象而不是作為一個ActiveX對象實現(xiàn)。而如今,在認識到實現(xiàn)這一類型的價值及安全性特征之后,微軟已經(jīng)在其IE 7中把XMLHttpRequest實現(xiàn)為一個窗口對象屬性。幸運的是,盡管其實現(xiàn)(因而也影響到調(diào)用方式)細節(jié)不同,但是,所有的瀏覽器實現(xiàn)都具有類似的功能,并且實質(zhì)上是相同方法。目前,W3C組織正在努力進行XMLHttpRequest對象的標準化,并且已經(jīng)發(fā)行了有關(guān)該W3C規(guī)范的一個草案。 本文將對XMLHttpRequest對象API進行詳細討論,并將解釋其所有的屬性和方法。 二、 XMLHttpRequest對象的屬性和事件 XMLHttpRequest對象暴露各種屬性、方法和事件以便于腳本處理和控制HTTP請求與響應(yīng)。下面,我們將對此展開詳細的討論。 readyState屬性 當XMLHttpRequest對象把一個HTTP請求發(fā)送到服務(wù)器時將經(jīng)歷若干種狀態(tài):一直等待直到請求被處理;然后,它才接收一個響應(yīng)。這樣以來,腳本才正確響應(yīng)各種狀態(tài)-XMLHttpRequest對象暴露一個描述對象的當前狀態(tài)的readyState屬性,如表格1所示。 表格1.XMLHttpRequest對象的ReadyState屬性值列表。 ReadyState取值 描述 0 描述一種"未初始化"狀態(tài);此時,已經(jīng)創(chuàng)建一個XMLHttpRequest對象,但是還沒有初始化。 1 描述一種"發(fā)送"狀態(tài);此時,代碼已經(jīng)調(diào)用了XMLHttpRequest open()方法并且XMLHttpRequest已經(jīng)準備好把一個請求發(fā)送到服務(wù)器。 2 描述一種"發(fā)送"狀態(tài);此時,已經(jīng)通過send()方法把一個請求發(fā)送到服務(wù)器端,但是還沒有收到一個響應(yīng)。 3 描述一種"正在接收"狀態(tài);此時,已經(jīng)接收到HTTP響應(yīng)頭部信息,但是消息體部分還沒有完全接收結(jié)束。 4 描述一種"已加載"狀態(tài);此時,響應(yīng)已經(jīng)被完全接收。 onreadystatechange事件 無論readyState值何時發(fā)生改變,XMLHttpRequest對象都會激發(fā)一個readystatechange事件。其中,onreadystatechange屬性接收一個EventListener值-向該方法指示無論readyState值何時發(fā)生改變,該對象都將激活。 responseText屬性 這個responseText屬性包含客戶端接收到的HTTP響應(yīng)的文本內(nèi)容。當readyState值為0、1或2時,responseText包含一個空字符串。當readyState值為3(正在接收)時,響應(yīng)中包含客戶端還未完成的響應(yīng)信息。當readyState為4(已加載)時,該responseText包含完整的響應(yīng)信息。 responseXML屬性 此responseXML屬性用于當接收到完整的HTTP響應(yīng)時(readyState為4)描述XML響應(yīng);此時,Content-Type頭部指定MIME(媒體)類型為text/xml,application/xml或以+xml結(jié)尾。如果Content-Type頭部并不包含這些媒體類型之一,那么responseXML的值為null。無論何時,只要readyState值不為4,那么該responseXML的值也為null。 其實,這個responseXML屬性值是一個文檔接口類型的對象,用來描述被分析的文檔。如果文檔不能被分析(例如,如果文檔不是良構(gòu)的或不支持文檔相應(yīng)的字符編碼),那么responseXML的值將為null。 status屬性 這個status屬性描述了HTTP狀態(tài)代碼,而且其類型為short。而且,僅當readyState值為3(正在接收中)或4(已加載)時,這個status屬性才可用。當readyState的值小于3時試圖存取status的值將引發(fā)一個異常。 statusText屬性 這個statusText屬性描述了HTTP狀態(tài)代碼文本;并且僅當readyState值為3或4才可用。當readyState為其它值時試圖存取statusText屬性將引發(fā)一個異常。 三、 XMLHttpRequest對象的方法 XMLHttpRequest對象提供了各種方法用于初始化和處理HTTP請求,下列將逐個展開詳細討論。 abort()方法 你可以使用這個abort()方法來暫停與一個XMLHttpRequest對象相聯(lián)系的HTTP請求,從而把該對象復位到未初始化狀態(tài)。 open()方法 你需要調(diào)用open(DOMString method,DOMString uri,boolean async,DOMString username,DOMString password)方法初始化一個XMLHttpRequest對象。其中,method參數(shù)是必須提供的-用于指定你想用來發(fā)送請求的HTTP方法(GET,POST,PUT,DELETE或HEAD)。為了把數(shù)據(jù)發(fā)送到服務(wù)器,應(yīng)該使用POST方法;為了從服務(wù)器端檢索數(shù)據(jù),應(yīng)該使用GET方法。另外,uri參數(shù)用于指定XMLHttpRequest對象把請求發(fā)送到的服務(wù)器相應(yīng)的URI。借助于window.document.baseURI屬性,該uri被解析為一個絕對的URI-換句話說,你可以使用相對的URI-它將使用與瀏覽器解析相對的URI一樣的方式被解析。async參數(shù)指定是否請求是異步的-缺省值為true。為了發(fā)送一個同步請求,需要把這個參數(shù)設(shè)置為false。對于要求認證的服務(wù)器,你可以提供可選的用戶名和口令參數(shù)。在調(diào)用open()方法后,XMLHttpRequest對象把它的readyState屬性設(shè)置為1(打開)并且把responseText、responseXML、status和statusText屬性復位到它們的初始值。另外,它還復位請求頭部。注意,如果你調(diào)用open()方法并且此時readyState為4,則XMLHttpRequest對象將復位這些值。 send()方法 在通過調(diào)用open()方法準備好一個請求之后,你需要把該請求發(fā)送到服務(wù)器。僅當readyState值為1時,你才可以調(diào)用send()方法;否則的話,XMLHttpRequest對象將引發(fā)一個異常。該請求被使用提供給open()方法的參數(shù)發(fā)送到服務(wù)器。當async參數(shù)為true時,send()方法立即返回,從而允許其它客戶端腳本處理繼續(xù)。在調(diào)用send()方法后,XMLHttpRequest對象把readyState的值設(shè)置為2(發(fā)送)。當服務(wù)器響應(yīng)時,在接收消息體之前,如果存在任何消息體的話,XMLHttpRequest對象將把readyState設(shè)置為3(正在接收中)。當請求完成加載時,它把readyState設(shè)置為4(已加載)。對于一個HEAD類型的請求,它將在把readyState值設(shè)置為3后再立即把它設(shè)置為4。 send()方法使用一個可選的參數(shù)-該參數(shù)可以包含可變類型的數(shù)據(jù)。典型地,你使用它并通過POST方法把數(shù)據(jù)發(fā)送到服務(wù)器。另外,你可以顯式地使用null參數(shù)調(diào)用send()方法,這與不用參數(shù)調(diào)用它一樣。對于大多數(shù)其它的數(shù)據(jù)類型,在調(diào)用send()方法之前,應(yīng)該使用setRequestHeader()方法(見后面的解釋)先設(shè)置Content-Type頭部。如果在send(data)方法中的data參數(shù)的類型為DOMString,那么,數(shù)據(jù)將被編碼為UTF-8。如果數(shù)據(jù)是Document類型,那么將使用由data.xmlEncoding指定的編碼串行化該數(shù)據(jù)。 setRequestHeader()方法 該setRequestHeader(DOMString header,DOMString value)方法用來設(shè)置請求的頭部信息。當readyState值為1時,你可以在調(diào)用open()方法后調(diào)用這個方法;否則,你將得到一個異常。 getResponseHeader()方法 getResponseHeader(DOMString header,value)方法用于檢索響應(yīng)的頭部值。僅當readyState值是3或4(換句話說,在響應(yīng)頭部可用以后)時,才可以調(diào)用這個方法;否則,該方法返回一個空字符串。 getAllResponseHeaders()方法 該getAllResponseHeaders()方法以一個字符串形式返回所有的響應(yīng)頭部(每一個頭部占單獨的一行)。如果readyState的值不是3或4,則該方法返回null。 四、 發(fā)送請求 在AJAX中,許多使用XMLHttpRequest的請求都是從一個HTML事件(例如一個調(diào)用JavaScript函數(shù)的按鈕點擊(onclick)或一個按鍵(onkeypress))中被初始化的。AJAX支持包括表單校驗在內(nèi)的各種應(yīng)用程序。有時,在填充表單的其它內(nèi)容之前要求校驗一個唯一的表單域。例如要求使用一個唯一的UserID來注冊表單。如果不是使用AJAX技術(shù)來校驗這個UserID域,那么整個表單都必須被填充和提交。如果該UserID不是有效的,這個表單必須被重新提交。例如,一個相應(yīng)于一個要求必須在服務(wù)器端進行校驗的Catalog ID的表單域可能按下列形式指定: <form name="validationForm" action="validateForm" method="post"> <table> <tr><td>Catalog Id:</td> <td> <input type="text" size="20" id="catalogId" name="catalogId" autocomplete="off" onkeyup="sendRequest()"> </td> <td><div id="validationMessage"></div></td> </tr> </table></form> 前面的HTML使用validationMessage div來顯示相應(yīng)于這個輸入域Catalog Id的一個校驗消息。onkeyup事件調(diào)用一個JavaScript sendRequest()函數(shù)。這個sendRequest()函數(shù)創(chuàng)建一個XMLHttpRequest對象。創(chuàng)建一個XMLHttpRequest對象的過程因瀏覽器實現(xiàn)的不同而有所區(qū)別。如果瀏覽器支持XMLHttpRequest對象作為一個窗口屬性(所有普通的瀏覽器都是這樣的,除了IE 5和IE 6之外),那么,代碼可以調(diào)用XMLHttpRequest的構(gòu)造器。如果瀏覽器把XMLHttpRequest對象實現(xiàn)為一個ActiveXObject對象(就象在IE 5和IE 6中一樣),那么,代碼可以使用ActiveXObject的構(gòu)造器。下面的函數(shù)將調(diào)用一個init()函數(shù),它負責檢查并決定要使用的適當?shù)膭?chuàng)建方法-在創(chuàng)建和返回對象之前。 <script type="text/javascript"> function sendRequest(){ var xmlHttpReq=init(); function init(){ if (window.XMLHttpRequest) { return new XMLHttpRequest(); } else if (window.ActiveXObject) { return new ActiveXObject("Microsoft.XMLHTTP"); } } </script> 接下來,你需要使用Open()方法初始化XMLHttpRequest對象-指定HTTP方法和要使用的服務(wù)器URL。 var catalogId=encodeURIComponent(document.getElementById("catalogId").value); xmlHttpReq.open("GET", "validateForm?catalogId=" + catalogId, true); 默認情況下,使用XMLHttpRequest發(fā)送的HTTP請求是異步進行的,但是你可以顯式地把async參數(shù)設(shè)置為true,如上面所展示的。 在這種情況下,對URL validateForm的調(diào)用將激活服務(wù)器端的一個servlet,但是你應(yīng)該能夠注意到服務(wù)器端技術(shù)不是根本性的;實際上,該URL可能是一個ASP,ASP.NET或PHP頁面或一個Web服務(wù)-這無關(guān)緊要,只要該頁面能夠返回一個響應(yīng)-指示CatalogID值是否是有效的-即可。因為你在作一個異步調(diào)用,所以你需要注冊一個XMLHttpRequest對象將調(diào)用的回調(diào)事件處理器-當它的readyState值改變時調(diào)用。記住,readyState值的改變將會激發(fā)一個readystatechange事件。你可以使用onreadystatechange屬性來注冊該回調(diào)事件處理器。 xmlHttpReq.onreadystatechange=processRequest; 然后,我們需要使用send()方法發(fā)送該請求。因為這個請求使用的是HTTP GET方法,所以,你可以在不指定參數(shù)或使用null參數(shù)的情況下調(diào)用send()方法。 xmlHttpReq.send(null); 五、 處理請求 在這個示例中,因為HTTP方法是GET,所以在服務(wù)器端的接收servlet將調(diào)用一個doGet()方法,該方法將檢索在URL中指定的catalogId參數(shù)值,并且從一個數(shù)據(jù)庫中檢查它的有效性。 本文示例中的這個servlet需要構(gòu)造一個發(fā)送到客戶端的響應(yīng);而且,這個示例返回的是XML類型,因此,它把響應(yīng)的HTTP內(nèi)容類型設(shè)置為text/xml并且把Cache-Control頭部設(shè)置為no-cache。設(shè)置Cache-Control頭部可以阻止瀏覽器簡單地從緩存中重載頁面。 public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { ... ... response.setContentType("text/xml"); response.setHeader("Cache-Control", "no-cache"); } 來自于服務(wù)器端的響應(yīng)是一個XML DOM對象,此對象將創(chuàng)建一個XML字符串-其中包含要在客戶端進行處理的指令。另外,該XML字符串必須有一個根元素。 out.println("<catalogId>valid</catalogId>"); 【注意】XMLHttpRequest對象的設(shè)計目的是為了處理由普通文本或XML組成的響應(yīng);但是,一個響應(yīng)也可能是另外一種類型,如果用戶代理(UA)支持這種內(nèi)容類型的話。 當請求狀態(tài)改變時,XMLHttpRequest對象調(diào)用使用onreadystatechange注冊的事件處理器。因此,在處理該響應(yīng)之前,你的事件處理器應(yīng)該首先檢查readyState的值和HTTP狀態(tài)。當請求完成加載(readyState值為4)并且響應(yīng)已經(jīng)完成(HTTP狀態(tài)為"OK")時,你就可以調(diào)用一個JavaScript函數(shù)來處理該響應(yīng)內(nèi)容。下列腳本負責在響應(yīng)完成時檢查相應(yīng)的值并調(diào)用一個processResponse()方法。 function processRequest(){ if(xmlHttpReq.readyState==4){ if(xmlHttpReq.status==200){ processResponse(); } } } 該processResponse()方法使用XMLHttpRequest對象的responseXML和responseText屬性來檢索HTTP響應(yīng)。如上面所解釋的,僅當在響應(yīng)的媒體類型是text/xml,application/xml或以+xml結(jié)尾時,這個responseXML才可用。這個responseText屬性將以普通文本形式返回響應(yīng)。對于一個XML響應(yīng),你將按如下方式檢索內(nèi)容: var msg=xmlHttpReq.responseXML; 借助于存儲在msg變量中的XML,你可以使用DOM方法getElementsByTagName()來檢索該元素的值: var catalogId=msg.getElementsByTagName("catalogId")[0].firstChild.nodeValue; 最后,通過更新Web頁面的validationMessage div中的HTML內(nèi)容并借助于innerHTML屬性,你可以測試該元素值以創(chuàng)建一個要顯示的消息: if(catalogId=="valid"){ var validationMessage = document.getElementById("validationMessage"); validationMessage.innerHTML = "Catalog Id is Valid"; } else { var validationMessage = document.getElementById("validationMessage"); validationMessage.innerHTML = "Catalog Id is not Valid"; } 六、 小結(jié) 上面就是XMLHttpRequest對象使用的所有細節(jié)實現(xiàn)。通過不必把Web頁面寄送到服務(wù)器而實現(xiàn)數(shù)據(jù)傳送,XMLHttpRequest對象為客戶端與服務(wù)器之間提供了一種動態(tài)的交互能力。你可以使用JavaScript啟動一個請求并處理相應(yīng)的返回值,然后使用瀏覽器的DOM方法更新頁面中的數(shù)據(jù)。
|
![]() |
|
Copyright © 木子火勺文武 | Powered by: 博客園 模板提供:滬江博客 |