摘 要AJAX用于實(shí)現(xiàn)瀏覽器與Web服務(wù)器之間的異步交互,AJAX框架通過封裝AJAX的基礎(chǔ)接口來簡化開發(fā)過程。基于AJAX框架實(shí)現(xiàn)對Web表單的自動保存,可提高Web應(yīng)用程序的健壯性和人性化。
關(guān)鍵詞 AJAX;XAJAX;框架;自動保存
中圖分類號:TP312 文獻(xiàn)標(biāo)識碼:A 文章編號:1671-489X(2008)06-0072-03
Implementation of Autosaving Function based on AJAX Framework//Qiu Ming,Jiang Hongxing,Wang Xinghui
Abstract AJAX can used to implement asynchronous interactivity between browser and web server.AJAX Framework facilitates AJAX programming by encapsulating the bottom interface of AJAX. Autosaving function that implemented by AJAX frameworks in web forms makes web applications robuster and more humanized.
Key words AJAX;XAJAX;framework;autosaving
1 引言
自動保存是指在用戶編輯文檔的過程中,應(yīng)用程序在后臺定時、自動地備份文檔,以防止某些意外情況造成文檔內(nèi)容的丟失。常用的桌面編輯軟件,例如Microsoft Word、Excel、WPS、3DMax,都具備自動保存的功能。一旦出現(xiàn)意外斷電、操作系統(tǒng)或應(yīng)用程序停止響應(yīng)等情況,即使編輯的內(nèi)容來不及手工保存,也可以利用自動保存的備份文件來恢復(fù)內(nèi)容,減少用戶的損失。
Web應(yīng)用程序利用Web表單來獲取用戶提交到服務(wù)器的內(nèi)容。用戶在瀏覽器軟件中填寫Web表單時,經(jīng)常碰到瀏覽器意外關(guān)閉或者表單提交失敗的情況,導(dǎo)致表單內(nèi)容丟失。尤其是在BBS、Blog和Email這些應(yīng)用中,輸入的文字量比較大,花費(fèi)時間長,表單內(nèi)容丟失的可能性更大,容易給用戶制造挫折感。因此,對健壯性和人性化要求高的Web應(yīng)用程序,有必要支持自動保存。Google的Gmail郵箱就提供自動保存功能。本文著重研究自動保存的機(jī)制,以源碼的形式闡述基于AJAX框架實(shí)現(xiàn)自動保存的方法,為各種Web應(yīng)用程序植入自動保存功能提供參考。

2 自動保存的機(jī)制
如圖1所示,用戶在Web表單中輸入的數(shù)據(jù),在手工提交到服務(wù)器之前稱為草稿。自動保存客戶端負(fù)責(zé)定時獲取當(dāng)前的草稿,完成檢驗(yàn)后把草稿提交到服務(wù)器端。自動保存服務(wù)器端負(fù)責(zé)響應(yīng)客戶端的保存請求,將草稿保存到數(shù)據(jù)庫中。自動保存的整個過程都是在后臺完成的,它在用戶填寫Web表單的過程中,并不顯示提交并刷新頁面,與用戶操作是互不干擾的、可同時發(fā)生的異步操作,可以利用AJAX來實(shí)現(xiàn)。
3 AJAX框架和XAJAX
3.1 AJAX框架AJAX(Asynchronous JavaScript and XML)是一種綜合運(yùn)用JavaScript、HTML、CSS、DOM、XML、XMLHttpRequest等技術(shù),實(shí)現(xiàn)客戶端瀏覽器與服務(wù)器端異步通信的Web開發(fā)方法。AJAX不是一種新技術(shù),但是與傳統(tǒng)的B/S交互模式相比,AJAX的主要優(yōu)勢有[1]:減輕服務(wù)器的負(fù)擔(dān);無刷新更新頁面,改善用戶體驗(yàn);分離數(shù)據(jù)與界面等。
AJAX在各種Web應(yīng)用中的工作原理都是相同的,基本上可以概括為2個環(huán)節(jié):1)在客戶端利用JavaScript創(chuàng)建XMLHttpRequest對象實(shí)例向服務(wù)器發(fā)送請求信息,并指定回調(diào)函數(shù);2)服務(wù)器完成數(shù)據(jù)處理并成功返回信息后,客戶端的回調(diào)函數(shù)做出響應(yīng),在回調(diào)函數(shù)中利用DOM處理返回的XML文檔信息或文本信息,并更新Web頁面內(nèi)容。
框架(Framework)是整個或部分系統(tǒng)的可重用設(shè)計(jì),表現(xiàn)為一組抽象中間件及中間件實(shí)例間交互的方法,是可被應(yīng)用開發(fā)者定制的應(yīng)用骨架[2]。基于框架的軟件開發(fā)是面向特定領(lǐng)域的重用基礎(chǔ),不僅能夠?qū)崿F(xiàn)代碼重用,而且可以有效實(shí)現(xiàn)系統(tǒng)分析和系統(tǒng)設(shè)計(jì)的重用[3]。利用已有的應(yīng)用框架,有助于提高軟件生產(chǎn)效率和質(zhì)量,開發(fā)出結(jié)構(gòu)良好、可維護(hù)性強(qiáng)的應(yīng)用系統(tǒng)。
AJAX框架是在抽象服務(wù)器與客戶端之間通信細(xì)節(jié)的基礎(chǔ)上,利用框架技術(shù)封裝了AJAX的基礎(chǔ)接口,為AJAX開發(fā)提供簡易、可重用的開發(fā)骨架。利用第三方提供的AJAX框架,開發(fā)人員可以集中精力開發(fā)業(yè)務(wù)邏輯。ajaxpatterns.org收集了200多個各種工作類型的AJAX框架。根據(jù)實(shí)現(xiàn)機(jī)制的不同,把AJAX框架分為瀏覽器端JavaScript框架和服務(wù)器端混合框架兩大類[4]。
3.2 XAJAX[5] XAJAX是一個基于PHP語言的AJAX服務(wù)器端開源框架,支持UTF-8字符集和Smarty模板。XAJAX設(shè)計(jì)巧妙,簡單易用,它使得服務(wù)器端響應(yīng)和反饋客戶端可以統(tǒng)一地用PHP語言來實(shí)現(xiàn)。在XAJAX中注冊過的服務(wù)器端的PHP函數(shù),可以方便地被客戶端的JavaScript調(diào)用。在調(diào)用過程中所需要的XMLHttp異步請求由XAJAX負(fù)責(zé)創(chuàng)建。
一般的AJAX框架需要開發(fā)人員用JavaScript編寫回調(diào)函數(shù),以便處理一個異步請求(即XMLHttp請求)返回的數(shù)據(jù),并且更新Web頁面的內(nèi)容。XAJAX框架簡化了這個繁瑣的過程,它的最大特色在于xajaxResponse類。xajaxResponse類允許開發(fā)人員利用PHP語言來反饋xajaxResponse XML指令,XML指令傳遞到客戶端后由XAJAX的指令分析器負(fù)責(zé)解析,并且按指令要求去控制Web頁面的內(nèi)容和狀態(tài)。圖2說明了XAJAX的工作過程。

xajaxResponse類包含許多把指令反饋到客戶端的指令函數(shù)。例如XAJAX 0.2版本中的addAssign($sTargetId,$sAttribute,$sData),可以將名稱為$sTargetId的HTML元素的$sAttribute屬性賦值為$sData。如果執(zhí)行以下PHP代碼:
$objResponse->addAssign(\"divResult\",\"innerHTML\",\"刪除操作成功!\");
執(zhí)行的結(jié)果是通知客戶端在頁面的DIV標(biāo)簽(divResult)中顯示\"刪除操作成功!\"字樣,相當(dāng)于在客戶端執(zhí)行Javascript腳本:
document.getElementById(“divResult”).innerHTML = \"刪除操作成功!\";
4 自動保存功能的具體實(shí)現(xiàn)
基于以上對XAJAX的介紹,下面介紹如何在Blog中實(shí)現(xiàn)定時自動保存。撰寫B(tài)log的頁面一般包括“保存并發(fā)布”、“保存為草稿”和“放棄保存”3個按鈕。手工保存(用戶點(diǎn)擊“保存并發(fā)布”和“保存為草稿”按鈕)與自動保存的大部分代碼相同,可以將手工保存與自動保存一同利用XAJAX來實(shí)現(xiàn)。下面依次陳述客戶端和服務(wù)器端的代碼邏輯。
4.1 自動保存客戶端在用戶填寫表單的過程中,定時判斷是否輸入了合法的、必要的內(nèi)容(例如Blog的標(biāo)題和Tag)。如果是,則開始執(zhí)行自動保存的提交過程。下面是自動保存客戶端 (autosave.js文件)中的主要的代碼片斷。
var intv=\"\";
var INTV_MS=120000;//自動保存時間間隔(120秒)
enableAutoSave(true);
function enableAutoSave(isEnable){ /* True表示開啟自動保存的定時器;反之關(guān)閉。*/
if(isEnable){ if(INTV_MS>0 intv==\"\") intv= window.setInterval(\"autoSave()\",INTV_MS); }
else{if(intv!=\"\"){ window.clearInterval(intv);intv= \"\";}}
return isEnable;
}
function autoSave(){
if(!checkData()) return 1; //檢測數(shù)據(jù)。如果沒有合法的必要數(shù)據(jù),跳出。
enableAutoSave(1);//關(guān)閉自動保存定時器
showSaveStatus(\"正在自動保存...\");//在頁面中提示正在自動保存
xajax_dosave(xajax.getFormValues ('frm_main'), 0 , gid(\"txt_editing_bid\").value);
}
上述代碼中,enableAutoSave函數(shù)用于開啟或關(guān)閉定時自動保存,瀏覽器定時執(zhí)行autoSave函數(shù),其中的關(guān)鍵語句是:
xajax_dosave(xajax.getFormValues ('frm_main'), act, gid(\"txt_editing_bid\").value)
xajax.getFormValues可以獲取frm_main表單中的所有數(shù)據(jù)(即用戶輸入的草稿),并且以數(shù)組返回。xajax_dosave函數(shù)由XAJAX自動生成,作用是創(chuàng)建自動保存的XMLHttp請求,將草稿提交到服務(wù)器端,它的3個參數(shù)與下面介紹服務(wù)器端的dosave函數(shù)相一致。
4.2 自動保存服務(wù)器端為方便管理,我們在數(shù)據(jù)庫中把自動保存的草稿與手工保存的Blog保存在同一張基本表中。假設(shè)用戶正在修改的Blog的編號為editing_bid(editing_bid為空表示是新的Blog),第一次自動保存editing_bid時,將新增一行記錄用來存放editing_bid的草稿(假設(shè)該草稿的編號為draft_bid)。需要說明的是,我們必須存儲editing_bid和draft_bid之間的關(guān)聯(lián)關(guān)系。只有這樣,后面第N次自動保存editing_bid時,只需修改draft_bid即可。
有多種方案可以存儲editing_bid和draft_bid之間的關(guān)聯(lián)關(guān)系,簡單易行的是采用Session。下面的save_draft_bid函數(shù)用于保存兩者的關(guān)聯(lián)關(guān)系,get_draft_bid函數(shù)用于提取editing_bid對應(yīng)的draft_bid。
function save_draft_bid($editing_bid,$draft_bid){ $_SESSION[‘DRAFT’. $editing_bid] = $draft_bid; }
function get_draft_bid($editing_bid){
return isset($_SESSION[‘DRAFT’. $editing_bid]) ? intval($_SESSION[‘DRAFT’. $editing_bid]): '';
}
自動保存服務(wù)器端的核心是autosave.server.php文件中的dosave函數(shù),它實(shí)現(xiàn)了自動保存和手工保存的業(yè)務(wù)邏輯,有3個參數(shù):$frm數(shù)組保存客戶端提交來的表單數(shù)據(jù),$action用于標(biāo)識動作的類型(1表示“保存為草稿”,2表示“保存并發(fā)布”,其他表示“自動保存”),$editing_bid表示正在編輯的Blog編號。
function dosave($frm,$action,$editing_bid){
global $CUR_UID; //當(dāng)前登錄用戶的Id
$action = intval($action);
if(empty($CUR_UID)){//一旦檢測到連接超時,調(diào)用客戶端的dologin()來彈出登錄對話框
$resp = new xajaxResponse();
$resp->addScript(\"dologin();\");
return $resp;
}
if( empty($frm) || !check_data($frm)) return new xajaxResponse();//檢測數(shù)據(jù),失敗則跳出
$draft_bid = get_draft_bid($editing_bid);
$resp = new xajaxResponse();
if($action==1 || $action==2){ //1-保存為草稿; 2-保存并發(fā)布
$frm['publish_status'] = $action==1? 1: 0;//Blog的發(fā)布狀態(tài):1草稿;0正式稿
if(!empty($editing_bid) exist_blog($editing_bid)){ //編輯中
$f=update_blog($editing_bid, $frm);
delete_blog($draft_bid);
save_draft_bid($editing_bid, ''); //清空draft_bid,表示draft_bid已經(jīng)不可用
}else{
if(!empty($draft_bid) exist_blog($draft_bid)){
$f=update_blog($draft_bid, $frm);
save_draft_bid($editing_bid, '');
}else{ $f = insert_blog($CUR_UID, $frm); }
}
$f ? $resp->addRedirect(\"blog_list.php\")/* 保存成功后跳轉(zhuǎn)*/
: $resp->addScript(\"dosave_info('保存失敗!');\");
}else{ //自動保存
$frm['publish_status'] = 1;
if(!empty($draft_bid) exist_blog($draft_bid)){ $f = update_blog($draft_bid, $frm); }
else{ $draft_bid = insert_blog($CUR_UID, $frm);
if($draft_bid) save_draft_bid($editing_bid, $draft_bid); }
}
return $resp;
}
dosave函數(shù)中的update_blog($editing_bid, $frm)用于修改編號為$editing_bid的記錄。delete_blog()和exist_blog()分別用于刪除Blog記錄、判斷Blog記錄是否存在。
5 結(jié)束語
自動保存可以提高用戶在輸入Web表單過程中的可靠性,降低操作系統(tǒng)、瀏覽器軟件、網(wǎng)絡(luò)故障等因素造成用戶丟失內(nèi)容的情況。本文論述了基于AJAX技術(shù)實(shí)現(xiàn)自動保存的具體方案,展示了關(guān)鍵部分的代碼邏輯,為其他應(yīng)用開展AJAX開發(fā)以及自動保存功能的開發(fā)提供了參考。XAJAX框架具有跨瀏覽器特性,經(jīng)測試,本文實(shí)現(xiàn)的自動保存功能可以兼容IE、Maxthon、Netscape和Firefox等主流瀏覽器。
參考文獻(xiàn):
[1]王星,潘郁.基于AJAX技術(shù)的Web模型在網(wǎng)站開發(fā)中的應(yīng)用研究[J].微計(jì)算機(jī)信息,2006(9-3):206-241
[2]郭妍旭,張波.框架技術(shù)在軟件開發(fā)中的研究與實(shí)踐[J].遼寧工學(xué)院學(xué)報,2006(12):379-382
[3]王成耀,姚琳.基于可重用框架的軟件開發(fā)模式及其應(yīng)用[J].計(jì)算機(jī)應(yīng)用研究,2003(1):49-51
[4]AJAX Frameworks[EB/OL].http://ajaxpatterns.org/Frameworks
[5]XAJAX官方網(wǎng)站[EB/OL].http://www.xajaxproject.org/