一、白話Ajax的原理
這個(gè)可以從 C/S 和 B/S 的原理說(shuō)起。Windows操作系統(tǒng)的誕生,為單機(jī)通信提供了很大的支持,程序設(shè)計(jì)也從早期DOS的單任務(wù)單用戶向網(wǎng)絡(luò)的分布式應(yīng)用過(guò)度。C/S提供的客戶/服務(wù)器編程模式為網(wǎng)絡(luò)應(yīng)用提供了一個(gè)有效的通信手段。瀏覽器與Web服務(wù)器之間的請(qǐng)求/ 服務(wù),就是一個(gè)典型的C/S應(yīng)用。
有人說(shuō),怎么是C/S?這應(yīng)該是B/S呀!其實(shí)是這樣理解的:瀏覽器/Web服務(wù)器作為我們實(shí)現(xiàn)網(wǎng)頁(yè)發(fā)布的一個(gè)平臺(tái),對(duì)于我們?cè)谶@個(gè)平臺(tái)上開(kāi)發(fā)的應(yīng)用,我們的應(yīng)用是由瀏覽器從Web服務(wù)器上下載下來(lái)然后展示在瀏覽器的“容器”里的,我們的應(yīng)用是B/S模式的。但是瀏覽器與Web服務(wù)器的通信,卻是C/S模式的。可以說(shuō),B/S模式是建立在C/S模式之上的。
Windows早期的桌面應(yīng)用程序(包括單機(jī)程序和C/S結(jié)構(gòu)的網(wǎng)絡(luò)應(yīng)用程序),其界面是調(diào)用Windows的API來(lái)實(shí)現(xiàn)的,后來(lái),出現(xiàn)了VB、Delph(VCL)、VC++(MFC)等應(yīng)用程序框架,把繁雜的API包裝起來(lái),使Windows程序開(kāi)發(fā)大大降低、效率大大提高。
進(jìn)入B/S編程階段后,我們只需要面向Web服務(wù)器和瀏覽器編程,不需要考慮網(wǎng)絡(luò)通信和并發(fā)等復(fù)雜的問(wèn)題。但是在瀏覽器和Web服務(wù)器之間,為了進(jìn)行數(shù)據(jù)交互,瀏覽器經(jīng)常頻繁的向Web服務(wù)器提交一些信息,現(xiàn)在的網(wǎng)絡(luò)環(huán)境又極差,使我們經(jīng)常等待于瀏覽器與Web服務(wù)器的通信狀態(tài),用戶體驗(yàn)很差。而傳統(tǒng)的桌面程序沒(méi)有這個(gè)缺陷。
怎樣既能利用B/S程序極強(qiáng)的界面表現(xiàn)力,又能避免其提交后的那一段眩暈的“真空”狀態(tài)呢?
其實(shí),在瀏覽器的設(shè)計(jì)階段,設(shè)計(jì)師已經(jīng)為我們考慮到了這個(gè)問(wèn)題。這就是我們要說(shuō)到的Ajax!Ajax英文是Asynchronous JavaScript and XML,就是在瀏覽器里通過(guò)一個(gè)機(jī)制,實(shí)現(xiàn)瀏覽器端與Web服務(wù)器端的一個(gè)異步通信,參與這個(gè)過(guò)程的有javascript、XML等技術(shù)。Ajax的引入,使B/S信息傳遞的量減少了,瀏覽器界面不再閃爍了,瀏覽者的感覺(jué)好多了。
Ajax并不是一項(xiàng)新技術(shù),而是幾個(gè)現(xiàn)有技術(shù)的新組合,而且它的發(fā)展也得益于幾家大的互聯(lián)網(wǎng)企業(yè)的率先應(yīng)用(大家常拿Google的在線Maps來(lái)舉例)。連瀏覽器寡頭微軟當(dāng)初都沒(méi)怎么看得起這項(xiàng)技術(shù),后來(lái)才在VS.NET2.0時(shí)代玩命的趕呀追。
二、Ajax的實(shí)現(xiàn)
Ajax是由瀏覽器通過(guò)內(nèi)部的一個(gè)組件實(shí)現(xiàn)的,這個(gè)組件負(fù)責(zé)接收用戶的請(qǐng)求,以XML作為信息中介,并與Web服務(wù)器實(shí)現(xiàn)異步通信,并把請(qǐng)求的結(jié)果返回給瀏覽器,再由瀏覽器呈現(xiàn)給用戶界面。“異步”的意思就是組件在后臺(tái)工作期間,瀏覽器與用戶保持在交互狀態(tài),并不更新當(dāng)前窗口。也不是所有的數(shù)據(jù)都被組件提交到后臺(tái)去。
Ajax實(shí)現(xiàn)的基礎(chǔ)是:瀏覽器有一個(gè)Ajax引擎;瀏覽器支持Javascript;Web服務(wù)器端也支持XML數(shù)據(jù)格式。并不是所有瀏覽器都支持Ajax技術(shù)的,但支持Ajax的瀏覽器越來(lái)越多。
這個(gè)組件在Windows下是一個(gè)COM組件,由IE瀏覽器調(diào)用。IE瀏覽器也是在5.0版本以后才提供這個(gè)組件的。不同的瀏覽器實(shí)現(xiàn)和創(chuàng)建XMLHttpRequest對(duì)象的方式是不太一樣的。但作為一個(gè)通用的Ajax接口,其外在表現(xiàn)是一致的。
Ajax其實(shí)是一項(xiàng)復(fù)雜的技術(shù),牽扯到的東西很多。除過(guò)XMLHttpRequest對(duì)象和Javascript,還有DOM(文檔對(duì)象模型),XML等。Javascript是一個(gè)粘合劑,它通過(guò)XMLHttpRequest對(duì)象對(duì)瀏覽器端頁(yè)面的諸多元素進(jìn)行操控,實(shí)現(xiàn)與Web服務(wù)器的后臺(tái)交互,實(shí)現(xiàn)數(shù)據(jù)驗(yàn)證、存取等功能。
三、Ajax編程示例
1,客戶端(文件client.htm)
<html>
<head>
<meta http-equiv=”Content-Type” content=”text/html; charset=gb2312″>
<title>AJAX 客戶端</title>
<script language=”javascript”>
var xmlhttp = false;
////開(kāi)始初始化XMLHttpRequest對(duì)象
//這段代碼考慮到了xmlhttp對(duì)象與目前主流瀏覽器的兼容
//如果在IE瀏覽器下測(cè)試,一條
//xmlhttp = new ActiveXObject(”Msxml2.XMLHTTP”)
//或xmlhttp = new ActiveXObject(”Microsoft.XMLHTTP”)語(yǔ)句就可以了
if(window.XMLHttpRequest)
{
//Mozilla 瀏覽器
xmlhttp = new XMLHttpRequest();
if (xmlhttp.overrideMimeType)
{//設(shè)置MiME類(lèi)別
xmlhttp.overrideMimeType(’text/xml’);
}
}
else
if (window.ActiveXObject)
{
// IE瀏覽器
try
{ xmlhttp = new ActiveXObject(”Msxml2.XMLHTTP”); }
catch (e)
{
try
{ xmlhttp = new ActiveXObject(”Microsoft.XMLHTTP”); }
catch (e)
{ }
}
}
function send_request(url, data)
{
//初始化、指定處理函數(shù)、發(fā)送請(qǐng)求的函數(shù)
if (!xmlhttp)
{ //異常,創(chuàng)建對(duì)象實(shí)例失敗
window.alert(”不能創(chuàng)建XMLHttpRequest對(duì)象實(shí)例.”);
return false;
}
// 確定發(fā)送請(qǐng)求的方式和URL以及是否同步執(zhí)行下段代碼
xmlhttp.open(”POST”, url, true);
xmlhttp.onreadystatechange = processRequest; //根據(jù)Web服務(wù)器應(yīng)答,觸發(fā)該狀態(tài)改變事件
xmlhttp.setRequestHeader(”Content-Type”,”application/x-www-form-urlencoded”);
xmlhttp.send(”username=” + data); //發(fā)送信息到后臺(tái)程序
}
////狀態(tài)改變事件處理函數(shù):處理返回的信息
function processRequest()
{
if (xmlhttp.readyState == 4)
{ // 判斷對(duì)象狀態(tài)
if (xmlhttp.status == 200) //正常返回信息,狀態(tài)編號(hào)200
{ // 信息已經(jīng)成功返回,開(kāi)始處理信息
alert(xmlhttp.responseText);
}
else
{ //頁(yè)面不正常
alert(”您所請(qǐng)求的頁(yè)面有異常。”);
}
}
}
function userCheck()
{
var f = document.form1;
var username = f.username.value;
if(username==”")
{
window.alert(”用戶名不能為空。”);
f.username.focus();
return false;
}
else
{
//該語(yǔ)句由用戶按“唯一性檢查”按鈕后執(zhí)行
send_request(’server.php’, username);
}
}
</script>
</head>
<body>
<body>
<form name=”form1″ action=”" method=”post”>
用戶名:<input type=”text” name=”username” value=”">
<input type=”button” name=”check” value=”惟一性檢查” onClick=”userCheck()”>
<input type=”submit” name=”submit” value=”提交”>
</form>
</body>
</html>
2,Web服務(wù)器端(文件server.php)
<?php
//取得客戶端數(shù)據(jù)
username = _POST[”username”];
//判斷用戶名的惟一性
if( username==”網(wǎng)眼”) //實(shí)際工程中,這里一般是從數(shù)據(jù)庫(kù)取用戶名的值
{
printf(”用戶名“%s”已經(jīng)被注冊(cè),請(qǐng)更換一個(gè)用戶名”, username);
}
else
{
printf(”用戶名“%s”尚未被使用,您可以繼續(xù)”, username);
}
?>
在以上Client.htm代碼中,首先建立XMLHttpRequest對(duì)象實(shí)例,然后很據(jù)對(duì)象的狀態(tài)觸發(fā)事件處理函數(shù),對(duì)返回的信息進(jìn)行處理。一切控制邏輯都是用Javascript腳本來(lái)書(shū)寫(xiě)的,XMLHttpRequest對(duì)象與Web服務(wù)器的XML信息交換對(duì)我們是隱含的,我們不必關(guān)心。
這是一個(gè)最原始的Ajax編程框架,它能簡(jiǎn)單的處理一些少量數(shù)據(jù)。經(jīng)過(guò)代碼重構(gòu),完全可以用在我們自己的小型工程中。
注意Ajax本身是一種瀏覽器端技術(shù),它和Web服務(wù)器端采用什么腳本書(shū)寫(xiě)代碼是沒(méi)有關(guān)系的。比如我們把Client.htm的語(yǔ)句send_request(’server.php’, username)換為send_request(’server.asp’, username),再相對(duì)應(yīng)的建立server.asp文件,內(nèi)容為:
<%
dim username
username = request(”username”)
if username=”Thomas” then
response.write(”用戶名” & username & “已經(jīng)被注冊(cè),請(qǐng)更換一個(gè)用戶名”)
else
response.write(”用戶名” & username & “尚未被使用,您可以繼續(xù)”)
end if
%>
做了這樣的改變后,在瀏覽器端,用戶看到的效果是一模一樣的。
新聞熱點(diǎn)
疑難解答
圖片精選