要說(shuō)Ajax就不得不說(shuō),異步傳輸和同步傳輸了。
異步是值:發(fā)送方發(fā)出數(shù)據(jù)后,不等接收方發(fā)回響應(yīng),接著發(fā)送下一個(gè)數(shù)據(jù)包的通訊方式。
同步是指:發(fā)送方發(fā)出數(shù)據(jù)后,等待接收方發(fā)回響應(yīng)以后才發(fā)下一個(gè)數(shù)據(jù)包的通訊方式。
也可以理解為:
異步傳輸:你傳吧,我去做我的事了,傳輸完了告訴我一聲。
同步傳輸:你現(xiàn)在傳輸,我要看著你傳輸完成,才去做別的事。
Ajax被認(rèn)為是(Asynchronous JavaScript and Xml)的縮寫。
現(xiàn)在,允許瀏覽器與服務(wù)器通信而無(wú)須刷新當(dāng)前頁(yè)面的技術(shù)成為Ajax。
Ajax的核心是JavaScript對(duì)象XmlHttpRequest。該對(duì)象在Internet Explorer5首次引入,它是一種支持異步請(qǐng)求的技術(shù)。簡(jiǎn)而言之,XmlHttpRequest使您可以使用JavaScript向服務(wù)器提出請(qǐng)求并處理響應(yīng),而不阻塞用戶。
Ajax采用異步交互過(guò)程。Ajax在用戶與服務(wù)器之間引入一個(gè)中間媒介,從而取消了網(wǎng)絡(luò)互聯(lián)過(guò)程中的處理-等待-處理-等待缺點(diǎn)。
用戶的瀏覽器在執(zhí)行任務(wù)時(shí)即加載了Ajax引擎。Ajax引擎使用JavaScript語(yǔ)言編寫,通常藏在一個(gè)隱藏的框架中。它負(fù)責(zé)編譯用戶界面與服務(wù)器之間的交互。
Ajax引擎允許用戶與應(yīng)用軟件之間的交互過(guò)程異步進(jìn)行,獨(dú)立于用戶與網(wǎng)路服務(wù)器間的交流。現(xiàn)在,可以用JavaScript調(diào)用Ajax引擎來(lái)代替產(chǎn)生一個(gè)HTTP的用戶動(dòng)作,內(nèi)存中的數(shù)據(jù)編輯,頁(yè)面導(dǎo)航,數(shù)據(jù)校驗(yàn)這些不需要重新載入整個(gè)頁(yè)面的需求可以交給Ajax來(lái)執(zhí)行。
使用Ajax,可以為Jsp,開發(fā)人員,終端用戶帶來(lái)可見的便捷。
Ajax并不是一項(xiàng)新技術(shù),其實(shí)是多種技術(shù)的綜合,包含JavaScript,XHtml和CSS,Dom,Xml和XmlHttpRequest技術(shù)。
服務(wù)器端語(yǔ)言:服務(wù)器需要具備向?yàn)g覽器發(fā)送特定信息的能力。Ajax與服務(wù)器端語(yǔ)言無(wú)關(guān)。
Xml(可擴(kuò)展標(biāo)記語(yǔ)言)是一種描述數(shù)據(jù)的格式。AJAX 程序需要某種格式化的格式來(lái)在服務(wù)器和客戶端之間傳遞信息,XML 是其中的一種選擇。
XHTML(eXtended Hypertext Markup Language,使用擴(kuò)展超媒體標(biāo)記語(yǔ)言)和 CSS(Cascading Style Sheet,級(jí)聯(lián)樣式單)標(biāo)準(zhǔn)化呈現(xiàn)。
DOM(Document Object Model,文檔對(duì)象模型)實(shí)現(xiàn)動(dòng)態(tài)顯示和交互。
使用XMLHTTP組件XMLHttpRequest對(duì)象進(jìn)行異步數(shù)據(jù)讀取。
使用JavaScript綁定和處理所有數(shù)據(jù)。
Ajax并不是完美的技術(shù),也存在缺陷:
AJAX大量使用了Javascript和AJAX引擎,而這個(gè)取決于瀏覽器的支持。IE5.0及以上、Mozilla1.0、NetScape7及以上版本才支持,Mozilla雖然也支持AJAX,但是提供XMLHttpRequest的方式不一樣。所以,使用AJAX的程序必須測(cè)試針對(duì)各個(gè)瀏覽器的兼容性。
AJAX更新頁(yè)面內(nèi)容的時(shí)候并沒(méi)有刷新整個(gè)頁(yè)面,因此,網(wǎng)頁(yè)的后退功能是失效的;有的用戶還經(jīng)常搞不清楚現(xiàn)在的數(shù)據(jù)是舊的還是已經(jīng)更新過(guò)的。這個(gè)就需要在明顯位置提醒用戶“數(shù)據(jù)已更新”。
對(duì)流媒體的支持沒(méi)有FLASH、Java Applet好。
XMLHttpRequest是XMLHTTP組件的對(duì)象,通過(guò)這個(gè)對(duì)象,AJAX可以像桌面應(yīng)用程序一樣只同服務(wù)器進(jìn)行數(shù)據(jù)層面的交換,而不用每次都刷新界面,也不用每次將數(shù)據(jù)處理的工作都交給服務(wù)器來(lái)做;這樣既減輕了服務(wù)器負(fù)擔(dān)又加快了響應(yīng)速度、縮短了用戶等待的時(shí)間。
XMLHttpRequest最早是在IE5中以ActiveX組件的形式實(shí)現(xiàn)的。非W3C標(biāo)準(zhǔn)。
創(chuàng)建XMLHttpRequest對(duì)象(由于非標(biāo)準(zhǔn)所以實(shí)現(xiàn)方法不統(tǒng)一):
Internet Explorer把XMLHttpRequest實(shí)現(xiàn)為一個(gè)ActiveX對(duì)象。
其他瀏覽器(Firefox、Safari、Opera…)把它實(shí)現(xiàn)為一個(gè)本地的JavaScript對(duì)象。
XMLHttpRequest在不同瀏覽器上的實(shí)現(xiàn)是兼容的,所以可以用同樣的方式訪問(wèn)XMLHttpRequest實(shí)例的屬性和方法,而不論這個(gè)實(shí)例創(chuàng)建的方法是什么。
初始化代碼如下:
function createXmlHttpRequest(){ var xmlHttp; try{ //Firefox, Opera 8.0+, Safari xmlHttp=new XMLHttpRequest(); }catch (e){ try{ //Internet Explorer xmlHttp=new ActiveXObject("Msxml2.XMLHTTP"); }catch (e){ try{ xmlHttp=new ActiveXObject("Microsoft.XMLHTTP"); }catch (e){} } } return xmlHttp; }
abort():停止當(dāng)前請(qǐng)求。
getAllResponseHeader():把HTTP請(qǐng)求的所有響應(yīng)首部作為key/value對(duì)返回。
getResponseHeader("headerLabel"):返回指定首部的串值。
open("method","url"):建立對(duì)服務(wù)器的調(diào)用,method參數(shù)可以是GET,POST。url參數(shù)可以是相對(duì)url或絕對(duì)url。這個(gè)方法還包含3個(gè)可選參數(shù)。
send(content):向服務(wù)器發(fā)送請(qǐng)求。
setRequestHeader("label","value"):把指定首部設(shè)置為所提供的值。在設(shè)置任何首部之前必須先調(diào)用open()方法。
onreadystatechange:狀態(tài)改變的事件觸發(fā)器。
readyState:對(duì)象狀態(tài):
0=未初始化
1=讀取中
2=已讀取
3=交互中
4=完成
responseText:服務(wù)器進(jìn)程返回?cái)?shù)據(jù)的文本版本。
responseXML:服務(wù)器進(jìn)程返回?cái)?shù)據(jù)的 兼容DOM的Xml文檔對(duì)象。
status:服務(wù)器返回的狀態(tài)碼,如404=“文件未找到”,200=“成功”。
statusText:服務(wù)器返回的狀態(tài)文本信息。
openreadystatechange事件處理函數(shù)。
該事件處理函數(shù)由服務(wù)器觸發(fā),而不是用戶。
在Ajax執(zhí)行過(guò)程中,服務(wù)器會(huì)通知客戶端當(dāng)前的通信狀態(tài)。這依靠更新 XMLHttpRequest 對(duì)象的 readyState 來(lái)實(shí)現(xiàn)。改變 readyState 屬性是服務(wù)器對(duì)客戶端連接操作的一種方式。
每次 readyState 屬性的改變都會(huì)觸發(fā) readystatechange事件,這個(gè)是核心。
open(method, url, asynch)方法。
XMLHttpRequest 對(duì)象的 open 方法允許程序員用一個(gè)Ajax調(diào)用向服務(wù)器發(fā)送請(qǐng)求。
method:請(qǐng)求類型,類似 “GET”或”POST”的字符串。若只想從服務(wù)器檢索一個(gè)文件,而不需要發(fā)送任何數(shù)據(jù),使用GET(可以在GET請(qǐng)求里通過(guò)附加在URL上的查詢字符串來(lái)發(fā)送數(shù)據(jù),不過(guò)數(shù)據(jù)大小限制為2000個(gè)字符)。若需要向服務(wù)器發(fā)送數(shù)據(jù),用POST。
在某些情況下,有些瀏覽器會(huì)把多個(gè)XMLHttpRequest請(qǐng)求的結(jié)果緩存在同一個(gè)URL。如果對(duì)每個(gè)請(qǐng)求的響應(yīng)不同,這就會(huì)帶來(lái)不好的結(jié)果。把當(dāng)前時(shí)間戳追加到URL的最后,就能確保URL的惟一性,從而避免瀏覽器緩存結(jié)果。
var url = "GetAndPostExample?timeStamp=" + new Date().getTime();
url:路徑字符串,指向你所請(qǐng)求的服務(wù)器上的那個(gè)文件。可以是絕對(duì)路徑或相對(duì)路徑。
asynch:表示請(qǐng)求是否要異步傳輸,默認(rèn)值為true(異步)。指定true,在讀取后面的腳本之前,不需要等待服務(wù)器的相應(yīng)。指定false,當(dāng)腳本處理過(guò)程經(jīng)過(guò)這點(diǎn)時(shí),會(huì)停下來(lái),一直等到Ajax請(qǐng)求執(zhí)行完畢再繼續(xù)執(zhí)行。
send(data)方法。
open 方法定義了 Ajax 請(qǐng)求的一些細(xì)節(jié)。send 方法可為已經(jīng)待命的請(qǐng)求發(fā)送指令。
data:將要傳遞給服務(wù)器的字符串。
若選用的是 GET 請(qǐng)求,則不會(huì)發(fā)送任何數(shù)據(jù), 給 send 方法傳遞 null 即可:request.send(null);
當(dāng)向send()方法提供參數(shù)時(shí),要確保open()中指定的方法是POST,如果沒(méi)有數(shù)據(jù)作為請(qǐng)求體的一部分發(fā)送,則使用null.
完整的 Ajax 的 GET 請(qǐng)求示例:
//創(chuàng)建Ajax引擎 var xmlHttpReq = createXmlHttpRequest(); xmlHttpReq.onreadystatechange=function(){ if(xmlHttpReq.readyState==4){ if(xmlHttpReq.status==200){ document.getElementById("info").innerHTML=xmlHttpReq.responseText; } } } xmlHttpReq.open("post","/webLogic/test_test.do",true);
setRequestHeader(header,value):
當(dāng)瀏覽器向服務(wù)器請(qǐng)求頁(yè)面時(shí),它會(huì)伴隨這個(gè)請(qǐng)求發(fā)送一組首部信息。這些首部信息是一系列描述請(qǐng)求的元數(shù)據(jù)(metadata)。首部信息用來(lái)聲明一個(gè)請(qǐng)求是 GET 還是 POST。
Ajax 請(qǐng)求中,發(fā)送首部信息的工作可以由 setRequestHeader完成。
參數(shù)header: 首部的名字; 參數(shù)value:首部的值。
如果用 POST 請(qǐng)求向服務(wù)器發(fā)送數(shù)據(jù),需要將 “Content-type” 的首部設(shè)置為 “application/x-www-form-urlencoded”.它會(huì)告知服務(wù)器正在發(fā)送數(shù)據(jù),并且數(shù)據(jù)已經(jīng)符合URL編碼了。
該方法必須在open()之后才能調(diào)用.
完整的 Ajax 的 POST 請(qǐng)求示例:
var xmlHttpReq = createXmlHttpRequest(); xmlHttpReq.onreadystatechange=function(){ if(xmlHttpReq.readyState==4){ if(xmlHttpReq.status==200){ document.getElementById("info").innerHTML=xmlHttpReq.responseText; } } } xmlHttpReq.open("post","/webLogic/test_test.do",true); xmlHttpReq.setRequestHeader("Content-Type","application/x-www-form-urlencoded"); xmlHttpReq.send("username="+"德瑪"+"&pwd="+"123");
用 XMLHttpRequest 的方法可向服務(wù)器發(fā)送請(qǐng)求。在 Ajax 處理過(guò)程中,XMLHttpRequest 的如下屬性可被服務(wù)器更改:
如果服務(wù)器返回的是 XML, 那么數(shù)據(jù)將儲(chǔ)存在 responseXML 屬性中。
只用服務(wù)器發(fā)送了帶有正確首部信息的數(shù)據(jù)時(shí), responseXML 屬性才是可用的。 MIME 類型必須為 text/xml。
XMLHttpRequest 的 responseText 屬性包含了從服務(wù)器發(fā)送的數(shù)據(jù)。它是一個(gè)HTML,XML或普通文本,這取決于服務(wù)器發(fā)送的內(nèi)容。
當(dāng) readyState 屬性值變成 4 時(shí), responseText 屬性才可用,表明 Ajax 請(qǐng)求已經(jīng)結(jié)束。
if(xmlHttpReq.readyState==4){ if(xmlHttpReq.status==200){ document.getElementById("info").innerHTML=xmlHttpReq.responseText; } }
服務(wù)器發(fā)送的每一個(gè)響應(yīng)也都帶有首部信息。三位數(shù)的狀態(tài)碼是服務(wù)器發(fā)送的響應(yīng)中最重要的首部信息,并且屬于超文本傳輸協(xié)議中的一部分。
常用狀態(tài)碼及其含義:
在 XMLHttpRequest 對(duì)象中,服務(wù)器發(fā)送的狀態(tài)碼都保存在 status 屬性里。通過(guò)把這個(gè)值和 200 或 304 比較,可以確保服務(wù)器是否已發(fā)送了一個(gè)成功的響應(yīng)
404 沒(méi)找到頁(yè)面(not found)
403 禁止訪問(wèn)(forbidden)
500 內(nèi)部服務(wù)器出錯(cuò)(internal service error)
200 一切正常(ok)
304 沒(méi)有被修改(not modified)(服務(wù)器返回304狀態(tài),表示源文件沒(méi)有被修改 )
readyState 屬性表示Ajax請(qǐng)求的當(dāng)前狀態(tài)。它的值用數(shù)字代表。
每次 readyState 值的改變,都會(huì)觸發(fā) readystatechange 事件。如果把 onreadystatechange 事件處理函數(shù)賦給一個(gè)函數(shù),那么每次 readyState 值的改變都會(huì)引發(fā)該函數(shù)的執(zhí)行。
readyState 值的變化會(huì)因?yàn)g覽器的不同而有所差異。但是,當(dāng)請(qǐng)求結(jié)束的時(shí)候,每個(gè)瀏覽器都會(huì)把 readyState 的值統(tǒng)一設(shè)為 4
0 代表未初始化。 還沒(méi)有調(diào)用 open 方法
1 代表正在加載。 open 方法已被調(diào)用,但 send 方法還沒(méi)有被調(diào)用
2 代表已加載完畢。send 已被調(diào)用。請(qǐng)求已經(jīng)開始
3 代表交互中。服務(wù)器正在發(fā)送響應(yīng)
4 代表完成。響應(yīng)發(fā)送完畢
readyState
status
responseText
responseXML
AJAX實(shí)質(zhì)上也是遵循Request/Server模式,所以這個(gè)框架基本的流程是:
responseText:將傳回的信息當(dāng)字符串使用;
responseXML:將傳回的信息當(dāng)XML文檔使用,可以用DOM處理。
function processResponse(){ if(XMLHttpReq.readyState==4){ //判斷對(duì)象狀態(tài) 4代表完成 if(XMLHttpReq.status==200){ //信息已經(jīng)成功返回,開始處理信息 document.getElementById("chatArea").value=XMLHttpReq.responseText; } } }
響應(yīng)需要做什么:
處理響應(yīng)處理函數(shù)都應(yīng)該做什么。
首先,它要檢查XMLHttpRequest對(duì)象的readyState值,判斷請(qǐng)求目前的狀態(tài)。參照前文的屬性表可以知道,readyState值為4的時(shí)候,代表服務(wù)器已經(jīng)傳回所有的信息,可以開始處理信息并更新頁(yè)面內(nèi)容了。如下:
if (http_request.readyState == 4) {
// 信息已經(jīng)返回,可以開始處理
} else {
// 信息還沒(méi)有返回,等待
}
服務(wù)器返回信息后,還需要判斷返回的HTTP狀態(tài)碼,確定返回的頁(yè)面沒(méi)有錯(cuò)誤。所有的狀態(tài)碼都可以在W3C的官方網(wǎng)站上查到。其中,200代表頁(yè)面正常。
if (http_request.status == 200) {
// 頁(yè)面正常,可以開始處理信息
} else {
// 頁(yè)面有問(wèn)題
}
向服務(wù)器發(fā)出HTTP請(qǐng)求了。這一步調(diào)用XMLHttpRequest對(duì)象的open和send方法。 http_request.open('GET', 'http://www.example.org/some.file', true);
http_request.send(null)
按照順序,open調(diào)用完畢之后要調(diào)用send方法。send的參數(shù)如果是以Post方式發(fā)出的話,可以是任何想傳給服務(wù)器的內(nèi)容。
注意:如果要傳文件或者Post內(nèi)容給服務(wù)器,必須先調(diào)用setRequestHeader方法,修改MIME類別。如下:
http_request.setRequestHeader(“Content-Type”,”application/x-www-form-urlencoded”);
這時(shí)資料則以查詢字符串的形式列出,作為send的參數(shù),例如:
name=value&anothername=othervalue&so=on
//發(fā)送請(qǐng)求 function sendRequest(){ //獲取文本框的值 var chatMsg=input.value; var url="chatServlet.do?charMsg="+chatMsg; //建立對(duì)服務(wù)器的調(diào)用 XMLHttpReq.open("POST",url,true); //設(shè)置MiME類別,如果用 POST 請(qǐng)求向服務(wù)器發(fā)送數(shù)據(jù), //需要將"Content-type" 的首部設(shè)置為 "application/x-www-form-urlencoded". //它會(huì)告知服務(wù)器正在發(fā)送數(shù)據(jù),并且數(shù)據(jù)已經(jīng)符合URL編碼了。 XMLHttpReq.setRequestHeader("Content-Type", "application/x-www-form-urlencoded"); //狀態(tài)改變的事件觸發(fā)器,客戶端的狀態(tài)改變會(huì)觸發(fā)readystatechange事件, //onreadystatechange會(huì)調(diào)用相應(yīng)的事件處理函數(shù) XMLHttpReq.onreadystatechange=processResponse; //發(fā)送數(shù)據(jù) XMLHttpReq.send(null); }
對(duì)象初始化
function createXmlHttpRequest(){ var xmlHttp; try{ //Firefox, Opera 8.0+, Safari xmlHttp=new XMLHttpRequest(); }catch (e){ try{ //Internet Explorer xmlHttp=new ActiveXObject("Msxml2.XMLHTTP"); }catch (e){ try{ xmlHttp=new ActiveXObject("Microsoft.XMLHTTP"); }catch (e){} } } return xmlHttp; }
發(fā)送請(qǐng)求
服務(wù)器接收
服務(wù)器響應(yīng)
客戶端接收,返回兩種格式:
修改客戶端頁(yè)面內(nèi)容。
只不過(guò)這個(gè)過(guò)程是異步的。
完整的如下:
var xmlHttpReq = createXmlHttpRequest(); xmlHttpReq.onreadystatechange=function(){ //為4表示請(qǐng)求和響應(yīng)結(jié)束 if(xmlHttpReq.readyState==4){ //200表示響應(yīng)成功 if(xmlHttpReq.status==200){ //在div上添加action返回的值 document.getElementById("info").innerHTML=xmlHttpReq.responseText; } } } //這是get方式發(fā)送數(shù)據(jù),中文記得在接受時(shí)進(jìn)行編碼 xmlHttpReq.open("post","/webLogic/test_test.do?username=aaa",true); //post請(qǐng)求時(shí)一定要加這個(gè)請(qǐng)求頭 // xmlHttpReq.setRequestHeader("Content-Type","application/x-www-form-urlencoded"); // xmlHttpReq.send("username="+"德瑪"+"&pwd="+"123");//這是post請(qǐng)求的發(fā)送數(shù)據(jù)方法 //get方式send(null),寫了也沒(méi)用 xmlHttpReq.send(null);
聲明:本網(wǎng)頁(yè)內(nèi)容旨在傳播知識(shí),若有侵權(quán)等問(wèn)題請(qǐng)及時(shí)與本網(wǎng)聯(lián)系,我們將在第一時(shí)間刪除處理。TEL:177 7030 7066 E-MAIL:11247931@qq.com