趙 勇 劉智濃 劉超華
摘 要:AJAX是近來興起的一種 Web 編程技術(shù)。事實上,AJAX不是一種技術(shù),而是幾種技術(shù)的集合。首先簡要介紹了AJAX的技術(shù),接著討論應(yīng)用AJAX技術(shù)開發(fā)高級Web應(yīng)用程序的方法和技術(shù)要點。實際中,建立了一個教學(xué)管理系統(tǒng),目前已投入使用,效果反映良好。
關(guān)鍵詞:AJAX;封裝;多態(tài)性;Web編程技術(shù)
中圖分類號:TP311文獻標識碼:A
文章編號:1004 373X(2009)02 114 03
Senior Web Application Development Technology Based on AJAX
ZHAO Yong,LIU Zhinong,LIU Chaohua
(Naval Flying Academic,Huludao,Liaoning,125001,China)
Abstract:AJAX is a new Web programming technology.In fact,AJAX is not a technology,but rather a collection of several technologies.AJAX technology,and the application of advanced technology development AJAX Web application methods are discussed and technical issues involved.A teaching management information system is built up and it has good effect in actual usage.
Keywords:AJAX;package;polymorphism;Web programming technology
1AJAX簡介
1.1AJAX定義
異步JavaScript和XML(AsynchronousJavaScriptand,XML,AJAX)是多種技術(shù)的綜合,包括 JavaScript,XHTML 和 CSS,DOM,XML 和 XSTL,XMLHttpRequest 。其特點是:使用 XHTML 和 CSS標準化呈現(xiàn);使用DOM 實現(xiàn)動態(tài)顯示和交互;使用 XML 和 XSTL 進行數(shù)據(jù)交換與處理;使用 XMLHttpRequest 進行異步數(shù)據(jù)讀取;最后用JavaScript 綁定和處理所有數(shù)據(jù)。
1.2AJAX的工作原理
與傳統(tǒng)的 Web 應(yīng)用不同,AJAX 采用異步交互過程。AJAX 在用戶與服務(wù)器之間引入一個中間媒介,從而消除了網(wǎng)絡(luò)交互過程中的處理-等待-處理-等待的缺點。用戶的瀏覽器在執(zhí)行任務(wù)時即裝載了 AJAX 引擎。AJAX引擎主要用JavaScript 語言編寫,通常藏在一個隱藏的框架中。它負責(zé)編譯用戶界面及與服務(wù)器之間的交互。AJAX引擎允許用戶與應(yīng)用軟件之間的交互過程異步進行,獨立于用戶與網(wǎng)絡(luò)服務(wù)器間的交流。現(xiàn)在,可以用JavaScript 調(diào)用AJAX引擎來代替產(chǎn)生一個直接的 HTTP請求的用戶動作,內(nèi)存中的數(shù)據(jù)編輯、數(shù)據(jù)校驗這些不需要重新載入整個頁面的需求可以交給AJAX執(zhí)行。AJAX最核心的理念是,傳統(tǒng)應(yīng)用中的瀏覽器直接與服務(wù)器交互,現(xiàn)在中間夾了一層 Script。也就是說,原來的Browser-Server 架構(gòu),現(xiàn)在是Browser-Ajax 引擎Server。假如是純粹的AJAX應(yīng)用,瀏覽器只向 AJAX 引擎發(fā)送消息,AJAX 引擎使用 XmlHttpRequest 向服務(wù)器發(fā)送請求,然后服務(wù)器在 XmlHttpRequest 的回復(fù)中帶上相關(guān)消息,最后 AJAX 引擎分析這些消息,用 HTMLDOM 模型處理界面。如此,理論上可以完全消除按頁刷新的需要。由于存在這樣一個在后臺的通信機制,原有開發(fā) Web 程序時碰到的問題自然內(nèi)部迎刃而解。最重要的是,使用了 AJAX框架不會與原有開發(fā)模型相沖突,如果處理得當AJAX的優(yōu)勢將顯而易見,加上兼容性,一定會使它有機會在 Web 領(lǐng)域中占一席之地 。
1.3 AJAX的優(yōu)點
與傳統(tǒng)的 Web 服務(wù)相比,AJAX具有明顯的優(yōu)勢:減輕了服務(wù)器的負擔(dān)。因為AJAX的根本理念是“按需取數(shù)據(jù)”,所以最大可能在減少了冗余請求和響應(yīng)對服務(wù)器造成的負擔(dān);非整頁地刷新、更新頁面,減少用戶實際和心理等待時間;更好的用戶體驗;也可以把以前的一些服務(wù)器負擔(dān)的工作轉(zhuǎn)嫁到客戶端,利于客戶端閑置的處理能力來處理,減輕服務(wù)器和帶寬的負擔(dān),節(jié)約空間和帶寬租用成本;可以異步調(diào)用外部數(shù)據(jù);其是基于標準化的并被廣泛支持的技術(shù),并且不需要插件或下載小程序;AJAX使Web中的界面與應(yīng)用分離,也可以說是數(shù)據(jù)與呈現(xiàn)分離;對于用戶和 ISP來說是雙贏的。
2AJAX技術(shù)的高級應(yīng)用研究
2.1 AJAX語言對象面向的JavaScript
由定義來看,JavaScript是典型的AJAX語言。不同于Java,JavaScript并不強調(diào)OO風(fēng)格的編碼。然而,JavaScript居然全面支持所有OO語言的主要屬性,即封裝、繼承和多態(tài)性。
數(shù)據(jù)類型:在Java中,一個類定義了一個數(shù)據(jù)及與它相關(guān)行為的組合。盡管JavaScript保留了class關(guān)鍵字,但是它不支持與常規(guī)OOP語言一樣的語義。在JavaScript中,對象是用函數(shù)來定義的。事實上,通過在下面的示例中定義一個函數(shù),就定義了一個簡單的空類Calculator:
function Calculator() {}
一個新實例的創(chuàng)建與在Java中相同使用new操作符:
var myCalculator = new Calculator();
上面函數(shù)不僅定義一個類,而且還擔(dān)當一個構(gòu)造器。在此,操作符new實現(xiàn)了實例化一個類Calculator的對象,并且返回一個對象參考而不是只調(diào)用該函數(shù)。
創(chuàng)建這樣的空類在實際中并沒有多大用處。下面,使用一個Java-腳本原型結(jié)構(gòu)填充類定義。JavaScript使用原型當作創(chuàng)建對象的模板。所有的原型屬性和方法都被參考引用復(fù)制到一個類的每個對象中,所以它們都具有相同的值。使用者可以改變一個對象中原型屬性的值,并且該新值會覆蓋從原型中復(fù)制過來的缺省值,但是這僅對于在一個實例中。下列語句將把一個新屬性添加到Calculator對象的原型上:
Calculator.prototype._prop = 0;
既然JavaScript并沒有提供一個方法來從句法上表示一個類定義,故將使用with語句來標記該類的定義邊界。這也將使得示例代碼更為短小,因為該with語句被允許在一個指定對象上執(zhí)行一系列的語句而不需要限制屬性。
function Calculator() {};
with (Calculator) {
prototype._prop = 0;
prototype.setProp = function(p) {_prop = p};
prototype.getProp = function() {return _prop};
}
到目前為止,定義并初始化了公共變量_prop,并且為它提供了getter和setter方法。
是否需要定義一個靜態(tài)變量。其中可以把靜態(tài)變量當作是為類所擁有的一個變量。因為在JavaScript中的類用函數(shù)對象來描述,所以只需要把一個新屬性添加到該函數(shù)上:
Calculator.iCount=0;
現(xiàn)在,既然iCount變量是一個Calculator對象的屬性,那么它將會被類Calculator的所有實例所共享。
function Calculator() {Calculator.iCount++;};
用上面的代碼可計算類Calculator的所有實例的個數(shù)。
封裝:通過使用上面所定義的“Calculator”,可以存取所有的“class”數(shù)據(jù);然而,它增加了派生類中命名沖突的危險性。明顯地需要封裝來把對象看作自包含的實體。
數(shù)據(jù)封裝的一種標準語言機制是使用私有變量,并且一個常用的、仿效一個私有變量的JavaScript技術(shù)是在構(gòu)造器中定義一個局部變量;這樣,該局部變量的存取只能經(jīng)由getter和setter來實現(xiàn),它們是該構(gòu)造器中的內(nèi)部函數(shù)。在下列實例中,_prop變量在Calculator函數(shù)中定義,并且在函數(shù)范圍外不可見。其中有兩個匿名的內(nèi)部函數(shù)(分別被賦予setProp和getProp屬性)存取“私有”變量。另外,需要注意,這里this的使用十分相似于它在Java中的用法:
function Calculator() {
var _prop = 0;
this.setProp = function (p){_prop = p};
this.getProp = function() {return _prop};
};
常被忽視的是在JavaScript中作如此封裝所付出的代價。須知,這種代價可能是巨大的,因為內(nèi)部函數(shù)對象對于該“class”的每一個實例被不斷地重復(fù)創(chuàng)建。
既然基于原型構(gòu)建對象速度更快,并且消費更少些的內(nèi)存,則在最強調(diào)性能的場所特別支持使用公共的變量。請注意,可以使用命名慣例來避免名稱沖突,例如在公共的變量前面加上該類名。繼承在表面看來,JavaScript缺乏對類層次的支持,這很相似于面向?qū)ο笳Z言的程序員對于現(xiàn)代語言的期盼。然而,盡管JavaScript句法沒有象Java一樣支持類繼承,但是仍然能夠在JavaScript中實現(xiàn)繼承,通過把已定義類的一個實例拷貝到其派生類的原型當中。
在提供例子之前,需要介紹一個constructor屬性。JavaScript保證每一個原型中都包含constructor,它擁有到該構(gòu)造器函數(shù)的一個參考。換句話說,Calculator.prototype.constructor包含一個到Calculator()的參考。
下面的代碼顯示了怎樣從基類Calculator派生類ArithmeticCalculator。其中,“第一行”取得類Calculator的所有屬性,而“第二行”把原型constructor的值恢復(fù)成ArithmeticCalculator:
function ArithmeticCalculator() { };
with (ArithmeticCalculator) {
ArithmeticCalculator.prototype = new Calculator();//第一行
prototype.constructor = ArithmeticCalculator;//第二行
}
上面的實例看起來像一個合成體而不是繼承,但是JavaScript引擎還是清楚這個原型鏈的。特別是,instanceof操作符會正確地適用于基類和派生類。假定創(chuàng)建類ArithmeticCalculator的一個新實例為:
var c = new ArithmeticCalculator;
則表達式c instanceof Calculator和c instanceof ArithmeticCalculator都會成立。
注意:在上面示例中基類的constructor是在初始化ArithmeticCalculator原型時被調(diào)用的,而在創(chuàng)建派生類的實例時并不被調(diào)用。這可能會帶來不想要的負面影響,而且為了實現(xiàn)初始化應(yīng)該考慮創(chuàng)建一個獨立的函數(shù)。由于該構(gòu)造器并不是一個成員函數(shù),所以它無法通過this參考引用調(diào)用。因此需要一個能調(diào)用超類的“Calculator”成員函數(shù):
function Calculator(ops) {…};
with (Calculator) { prototype.Calculator=Calculator;}
現(xiàn)在,可以寫一個繼承類,它顯示地調(diào)用基類的構(gòu)造器:
function ArithmeticCalculator(ops) { this.Calculator(ops);};
with (ArithmeticCalculator) {
ArithmeticCalculator.prototype = new Calculator;
prototype.constructor = ArithmeticCalculator;
prototype.ArithmeticCalculator = ArithmeticCalculator;
}
多態(tài)性:JavaScript是一種非類型化的語言。在此,一切都是對象。因此,如果有2個類A和B,它們都定義一個foo(),則JavaScript將允許在A和B的實例上多態(tài)地調(diào)用foo(),即使不存在層次關(guān)系(雖然是可實現(xiàn)的)。從這一角度來看,JavaScript提供一個比Java更寬的多態(tài)性。這種靈活性,也要付出代價。在這種情況中,代價是把類型檢查工作代理到應(yīng)用程序代碼。具體地說,如果需要檢查一個參考確實指向一個所希望的基類,則可以通過instanceof操作符來實現(xiàn)。
另一方面,JavaScript并不檢查函數(shù)調(diào)用中的參數(shù):這可以防止用一樣的命名和不同的參數(shù)來定義多態(tài)函數(shù)(并且讓編譯器選擇正確的簽名)。代之的是,JavaScript提供了一個Java 5風(fēng)格的函數(shù)范圍內(nèi)的argument對象;它允許你根據(jù)參數(shù)的類型和數(shù)量的不同實現(xiàn)一個不同的行為。
2.2AJAX組件授權(quán)
所有的AJAX組件授權(quán)方案在現(xiàn)在被邏輯地分成兩組。具體地說,第一組用于與基于HTML的UI定義的無縫集成。第二組把HTML當作一個UI定義語言以支持某種XML。在此,從第一組中來展示一種方法;雖然它存在于瀏覽器之中卻是類似于JSP標簽。這些瀏覽器特定的組件授權(quán)擴展在IE情形下稱作元素行為,而在最近版本的Firefox,Mozilla和Netscape 8情形下稱作可擴展的綁定。
2.3定制標簽
Internet Explorer,從版本5.5開始,支持定制的客戶端HTML元素的JavaScript授權(quán)。不象JSP標簽,這些對象并沒有在服務(wù)器端被預(yù)處理到HTML中。而是,它們成為一標準HTML對象模型的合法擴展,并且包括構(gòu)造控件在內(nèi)的一切事情,都是動態(tài)地發(fā)生在客戶端的。同樣,基于Gecko-引擎的瀏覽器能夠用一個可重用功能動態(tài)地裝飾任何現(xiàn)有的HTML元素。
因此,有可能用具有HTML語法的方法、事件和屬性來構(gòu)建一個具有豐富UI組件的庫。這樣的組件可以被自由地混合于標準HTML中。在內(nèi)部,這些組件將會與應(yīng)用程序服務(wù)器進行通信,即AJAX風(fēng)格。換句話說,使用者有可能(并且相對簡單地)構(gòu)建自己的AJAX對象模型。
3 結(jié) 語
本單位應(yīng)用以上技術(shù)建立了教學(xué)管理信息系統(tǒng),目前已經(jīng)投入使用,效果反映良好。
參考文獻
[1]陳瓊.AJAX老技術(shù),新外衣[J].互聯(lián)網(wǎng)周刊,2005,8(27):52-53.
[2]夏桅.AJAX with ASP.NETJ.MSDN開發(fā)精選,2005(4):230-231.
[3]王沛,馮曼菲.征服AjaxWeb 2.0開發(fā)技術(shù)詳解[M].北京:人民郵電出版社,2006.
[4]楊華.AJAX及在ASP.NET中的實現(xiàn)[J].現(xiàn)代電子技術(shù),2006,29(12):79-83.
[5]朱德利.Web2.0的技術(shù)特點和信息傳播思想[J].現(xiàn)代情報,2005,25(12):74-77.
[6]田原.基于AJAX的教學(xué)Web應(yīng)用.遼寧工程技術(shù)大學(xué):自然科學(xué)版,2007(5):737-739.
[7]游麗貞,郭宇春,李純喜.Ajax引擎的原理和應(yīng)用[J].微計算機信息,2006,22(6):250-208.
[8]田園,唐鑄文.MXL與VisualBasic.NET編程技術(shù)[M].北京:科學(xué)出版社,2006.
作者簡介 趙 勇 教員。研究方向為信息系統(tǒng),模擬仿真。
劉智濃 副教授。研究方向為網(wǎng)絡(luò)安全。
劉超華 講師。主要從事計算機教學(xué)科研工作。