摘 要:Ajax的主要特點(diǎn)在于異步交互,更新web頁(yè)面的局部信息。本文分析了Ajax的實(shí)現(xiàn)原理,通過(guò)實(shí)例介紹了Ajax常用的四種開(kāi)發(fā)模式。
關(guān)鍵詞:異步交互Ajax開(kāi)發(fā)模式
中圖分類號(hào):TP393.02文獻(xiàn)標(biāo)識(shí)碼:A文章編號(hào):1674-098X(2011)01(a)-0028-02
在傳統(tǒng)的web應(yīng)用中,用戶使用瀏覽器瀏覽網(wǎng)頁(yè),瀏覽器等待刷新,當(dāng)網(wǎng)頁(yè)刷新很慢時(shí),屏幕內(nèi)容一片空白,用戶只能在屏幕前等待瀏覽器的響應(yīng)。這是因?yàn)閭鹘y(tǒng)的web應(yīng)用采用同步交互過(guò)程,即用戶首先向服務(wù)器發(fā)送一個(gè)請(qǐng)求,服務(wù)器接收到用戶的請(qǐng)求后開(kāi)始執(zhí)行用戶請(qǐng)求的操作,最后將結(jié)果返回給瀏覽器。在服務(wù)器處理時(shí),用戶只能等待。這是一種不連貫的用戶體驗(yàn)。
當(dāng)負(fù)載較小時(shí),這種方式?jīng)]有體現(xiàn)出什么問(wèn)題。可是當(dāng)負(fù)載較大時(shí),響應(yīng)時(shí)間可能比較長(zhǎng),用戶等待時(shí)間也較長(zhǎng)。另外,有時(shí)用戶只需要更新頁(yè)面的部分?jǐn)?shù)據(jù),而不需要更新整個(gè)頁(yè)面。在軟件設(shè)計(jì)越來(lái)越人性化的時(shí)候,我們應(yīng)該通過(guò)一定的方法來(lái)改進(jìn)用戶體驗(yàn)。由此產(chǎn)生了異步的工作方式。例如在輸入表單時(shí),在異步的工作方式下,當(dāng)用戶輸入部分內(nèi)容的時(shí)候,服務(wù)器可以先檢查輸入的內(nèi)容。異步交互、局部更新正是Ajax可以實(shí)現(xiàn)的功能。
1 Ajax的實(shí)現(xiàn)原理
Ajax應(yīng)用程序的加載和傳統(tǒng)的web應(yīng)用程序沒(méi)什么區(qū)別:首先,某個(gè)用戶操作引發(fā)了瀏覽器的一次HTTP請(qǐng)求。然后服務(wù)器處理這個(gè)請(qǐng)求。生成合適的HTML、CSS以及Javascript,并發(fā)送至客戶端。最后,客戶端瀏覽器將這一段HTML顯示出來(lái)。
隨后,用戶在該Ajax頁(yè)面上的后續(xù)操作將和傳統(tǒng)web頁(yè)面完全不同。用戶的操作將不會(huì)引發(fā)瀏覽器的另一次HTTP請(qǐng)求,取而代之的是將引發(fā)客戶端的某段JavaScript代碼的執(zhí)行。一次用戶操作的全過(guò)程可以分為7個(gè)步驟:
(1)用戶在頁(yè)面上執(zhí)行了某個(gè)操作,例如點(diǎn)擊某個(gè)按鈕等;
(2)根據(jù)用戶的操作,頁(yè)面發(fā)出相應(yīng)的DHTML事件;
(3)調(diào)用注冊(cè)到該DHTML事件的客戶端JavaScript事件處理函數(shù),其中初始化了一個(gè)用以向服務(wù)器發(fā)送異步請(qǐng)求的XMLHttpRequest對(duì)象,同時(shí)指定一個(gè)回調(diào)函數(shù),當(dāng)服務(wù)器端的響應(yīng)返回時(shí),將自動(dòng)調(diào)用該回調(diào)函數(shù);
(4)服務(wù)器收到XMLHttpRequest對(duì)象的請(qǐng)求后,開(kāi)始根據(jù)請(qǐng)求進(jìn)行一系列的處理;
(5)處理完畢,服務(wù)器返回客戶端所需要的數(shù)據(jù);
(6)數(shù)據(jù)到達(dá)客戶端之后,執(zhí)行JavaScript回調(diào)函數(shù),并根據(jù)返回的數(shù)據(jù)對(duì)用戶界面進(jìn)行更新。
(7)用戶看到界面的變化。
在整個(gè)過(guò)程中,用戶并沒(méi)有被阻塞,依然可以瀏覽當(dāng)前頁(yè)面的其他部分,甚至還可以再引發(fā)事件并觸發(fā)另一個(gè)與服務(wù)器的異步交互過(guò)程。這種模式即非阻塞的異步通信模式,在用戶體驗(yàn)方面有很大的進(jìn)步。
2 Ajax的開(kāi)發(fā)模式
目前,Ajax技術(shù)沒(méi)有統(tǒng)一的開(kāi)發(fā)模式。不同的開(kāi)發(fā)模式針對(duì)不同的Ajax項(xiàng)目在實(shí)現(xiàn)上有一些差別。下面介紹Ajax常見(jiàn)的四種開(kāi)發(fā)模式。
2.1 XMLHTTP+WebForms
XMLHTTP+WebForms是使用Ajax技術(shù)進(jìn)行web應(yīng)用開(kāi)發(fā)的最基本方法。在這種模式下,通過(guò)JavaScript去操作XMLHttpRequest對(duì)象,發(fā)送異步請(qǐng)求到服務(wù)器端。另一方面,在服務(wù)器端可以直接接受XMLHttpRequest的請(qǐng)求。并根據(jù)請(qǐng)求進(jìn)行相對(duì)應(yīng)的處理,處理完成后返回相應(yīng)的執(zhí)行結(jié)果給XMLHttpRequest對(duì)象。最后再直接使用JavaScript語(yǔ)言代碼將返回的結(jié)果顯示出來(lái)。下面用這種方法實(shí)現(xiàn)一個(gè)輸入小寫字母,點(diǎn)擊按鈕,轉(zhuǎn)換為大寫字母輸出的頁(yè)面。如圖 1所示。
主要代碼如下:
(1) 客戶端
客戶端里創(chuàng)建XMLHttpRequest對(duì)象以及發(fā)起異步請(qǐng)求、回調(diào)處理。
創(chuàng)建XMLHttpRequest對(duì)象。
varxmlHttp=1;
function creatXMLHTTP()
{
//根據(jù)瀏覽器的不同,創(chuàng)建XMLHttpRequest對(duì)象。
}
發(fā)起異步請(qǐng)求。
function sendRequest(url)
{creatXMLHTTP();
xmlHttp.open(\"GET\",url,true);
xmlHttp.onreadystatechange=httpStateChange; //指定響應(yīng)函數(shù)
xmlHttp.send(1);//發(fā)送請(qǐng)求
}
回調(diào)處理函數(shù)。
functionhttpStateChange(){
if(xmlHttp.readyState==4){//判斷對(duì)象狀態(tài)
if(xmlHttp.status==200)//信息已經(jīng)成功返回、開(kāi)始處理信息
{vara=xmlHttp.responseText;
document.form1.result.value=a;//顯示服務(wù)器傳回的信息
} else{
window.alert(\"異常\");
}}}
functionusercheck()
{
vartest=document.form1.testmsg.value;
if(test==\"\")
{window.alert(\"輸入不能為空\(chéng)");
return1;}
else{
varurl=\"ajax.aspx?test=\"+test;
sendRequest(url)
}
頁(yè)面上的控件代碼如下:
(2)服務(wù)器端
服務(wù)器端就是一個(gè)WebForm,接受客戶端傳遞的參數(shù)然后將其轉(zhuǎn)化為大寫后返回給客戶端。本例中WebForm為ajax.aspx。
protected void Page_Load(object sender, EventArgs e){
if (!IsPostBack){
string test = Request.QueryString[\"test\"].ToString().Trim();
string result = test.ToUpper();
Response.Write(result);
Response.Flush();
Response.End();
}}
2.2 XMLHTTP+HttpHandler
XMLHTTP+HttpHandler模式與XMLHTTP+WebForms模式相比,客戶端的實(shí)現(xiàn)并沒(méi)有變化,還是直接使用JavaScript語(yǔ)言代碼操作XMLHTTP對(duì)象,但在服務(wù)器端已經(jīng)改用HttpHandler接收和處理異步請(qǐng)求。下面用這種方式來(lái)實(shí)現(xiàn)小寫轉(zhuǎn)大寫的例子。
(1)客戶端
在上面的例子中只需要更改發(fā)送請(qǐng)求函數(shù)的url。主要代碼如下:
function sendRequest(){
creatXMLHTTP();
var url=\"hello.ashx?name=\"+document.getElementById(‘testmsg’).value;
xmlHttp.open(\"GET\",url,true);
xmlHttp.onreadystatechange=onSuccessCallBack;
xmlHttp.send(1);
}
(2)服務(wù)器端
服務(wù)器端編寫一般處理程序文件hello.ashx,代碼如下:
public class hello: IHttpHandler{
public void ProcessRequest(HttpContext context){
context.Response.ContentType=\"text/plain\";
string name=context.Request.QueryString[\"name\"];
context.Response.Write(name.ToUpper());}
public bool IsReusable{
get{
return 1;}}}
2.3 CallBack
CallBack是ASP.NET 2.0新增的開(kāi)發(fā)方式。它要求頁(yè)面實(shí)現(xiàn)ICallbackEventHandler接口。ASP.NET的回調(diào),就是使用ICallbackEventHandler接口。它包括兩個(gè)方法:RaiseCallbackEvent0方法執(zhí)行對(duì)異步請(qǐng)求的服務(wù)器端處理;GetCallBackResult0方法返回異步請(qǐng)求的處理結(jié)果。通過(guò)實(shí)現(xiàn)RaiseCallbackEvent()和GetCallbackResult()方法來(lái)實(shí)現(xiàn)回調(diào),最后通過(guò)調(diào)用ClientScript.GetCallbackEventReference()方法實(shí)現(xiàn)Ajax效果。下面用這種方式來(lái)實(shí)現(xiàn)小寫轉(zhuǎn)大寫的例子。
(1)客戶端
客戶端通過(guò)調(diào)用ClientScript.GetCallbackEventReference()方法,來(lái)實(shí)現(xiàn)Ajax,主要代碼如下:
接收服務(wù)器返回的數(shù)據(jù),在頁(yè)面顯示出來(lái)。
function ReceiveServerData(arg, context)
{
document.getElementById (\"result\").value=arg;
}
向服務(wù)器發(fā)送請(qǐng)求,設(shè)置回調(diào)處理函數(shù)。
function CallTheServer(arg, context)
{
<%= ClientScript.GetCallbackEventReference(this, \"arg\", \"ReceiveServerData\", \"context\") %>;
}
button控件通過(guò)調(diào)用CallTheServer去回調(diào)服務(wù)器端的方法,頁(yè)面上的主要控件代碼如下:
提交給服務(wù)器的CallBack
(2)服務(wù)器端
服務(wù)器端實(shí)現(xiàn)了ICallbackEventHandler,在RaiseCallbackEvent方法里接收瀏覽器以CallBack機(jī)制傳過(guò)來(lái)的值,GetCallbackResult()將大寫值返回給瀏覽器。主要代碼如下:
public partial class Default8 : System.Web.UI.Page, ICallbackEventHandler
{
string str = \"\";
public void RaiseCallbackEvent(String eventArgument)
{
str = eventArgument.ToUpper();}// 返回給CallBack的字符串
public string GetCallbackResult()
{return str;}}
2.4 AJAX框架
Ajax框架現(xiàn)在已有很多,通常情況下將基于瀏覽器的應(yīng)用框架稱為客戶端框架,如Prototype、DOJO、qooxdoo、Bindows等;還有基于服務(wù)器端的框架,如ASP.NET Ajax、Ajax.NET、WebORB for.NET、ComfortASP.NET、AjaxAspects等。通過(guò)使用Ajax框架進(jìn)行web開(kāi)發(fā)可以提高效率,并且代碼穩(wěn)定性好。
ScriptManager是放置在web窗體上的服務(wù)器端控件,在ASP.NET Ajax中發(fā)揮核心作用。UpdatePanel控件的使用可以大大減少客戶端腳本的編寫工作量,它不需要編寫任何客戶端腳本,只要在一個(gè)頁(yè)面上添加幾個(gè)UpdatePanel控件和一個(gè)ScriptManager控件就可以實(shí)現(xiàn)頁(yè)面的局部更新。下面使用ASP.NET Ajax來(lái)實(shí)現(xiàn)小寫轉(zhuǎn)大寫的例子。在頁(yè)面添加ScriptManager和UpdatePanel控件來(lái)實(shí)現(xiàn)頁(yè)面的局部更新。頁(yè)面主要代碼如下:
服務(wù)器端代碼如下:
protected void Button1_Click(object sender, EventArgs e)
{ string a = TextBox1.Text.Trim();
string b = a.ToUpper();
TextBox2.Text = b;
}
3 結(jié)束語(yǔ)
Ajax的四種開(kāi)發(fā)模式各有特點(diǎn),前三種方法相比成型的Ajax框架來(lái)說(shuō)使用起來(lái)比較麻煩,沒(méi)有框架那么直接,不過(guò)各自也有各自的好處。所有的Ajax框架都會(huì)調(diào)用一大堆并不需要的代碼,雖然開(kāi)發(fā)效率增加了,但會(huì)嚴(yán)重影響運(yùn)行效率。如果JavaScript設(shè)計(jì)得好,效率會(huì)比使用一些Ajax框架高出很多。在我們的實(shí)際開(kāi)發(fā)中應(yīng)該根據(jù)實(shí)際需求來(lái)選擇適合自己的Ajax模式。
參考文獻(xiàn)
[1]陳黎夫.ASP.NET Ajax程序設(shè)計(jì)[M].人民郵電出版社,2007.
[2]凌宗軍.Ajax級(jí)聯(lián)菜單的實(shí)現(xiàn)[J].科技創(chuàng)新導(dǎo)報(bào),2009,16:25.
[3]王玉娟.AJAX技術(shù)及其優(yōu)缺點(diǎn)[J].科技創(chuàng)新導(dǎo)報(bào),2009,8:16.