作者: Jonathan Fenocchi
時間:2005.10.25
譯者:Sheneyan
英文原文:
http://webreference.com/programming/javascript/jf/column12/index.html
在過去,由於為了獲得新資料而不得不重新載入web頁面(或者載入其他頁面)導致web應用程式發展被限制。雖然有其他方法可用(不載入其他頁面),但是這些技術都沒有被很好地支援而且有bug成災的趨向。在過去的幾個月裡,一個過去並不被廣泛支援的技術已經被越來越多的web衝浪者(web surfers??是指瀏覽器還是瀏覽者?)所接受,它給了開發人員更多的自由開發先進的web應用程式。這些通過javascript來非同步取得xml資料的應用程式,被親切的稱為“Ajax應用程式”(Asynchronous Javascript and XML applications)。在這篇文章中,我將會解釋如何通過Ajax來取回一個遠端XML檔案並更新一個web page,並且隨著這個系列的繼續,我將討論更多的方法,使用ajax技術將你的web應用程式提升到一個新的層次.
這第一步就是建立一個帶一些資料的XML檔案。我們將這個檔案命名為data.xml。它是一個簡單的XML檔案,而在一個真實的程式中,它會複雜許多,但對於我們的例子來說,簡單明了是最合適地。
<?xml version="1.0" encoding="UTF-8"?> <root> <data> 這是一些樣本資料,它被儲存在一個XML檔案中,並被JavaScript取回。 </data> </root>
現在讓我們建立一個簡單的web頁麵包含一些樣本資料。這個頁面將是我們的js指令碼所在,並且這個頁面將會讓使用者們訪問柄看到Ajax指令碼的運行。我們把它命名為ajax.html
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<html lang="zh" dir="ltr">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
<title>使用ajax開發web應用程式 - 樣本</title>
</head>
<body>
<h1>使用ajax開發web應用程式</h1>
<p>這個頁面示範了AJAX技術如何通過動態讀取一個遠程檔案來更新一個網頁的內容--不需要任何網頁的重新載入。注意:這個例子對于禁止js的使用者來說沒有效果。</p>
<p id="xmlObj">
這是一些樣本資料,它是這個網頁的預設資料 <a href="data.xml"
title="查看這個XML資料." onclick="ajaxRead('data.xml'); this.style.display='none'; return false">查看XML資料.</a>
</p>
</body>
</html>
注意,對於那些沒有javascript的使用者,我們直接連結到data.xml檔案。對於那些允許運行javascript的使用者,函數“ajaxRead”將被運行,這個連結被隱藏,並不會被轉向到那個data.xml檔案。函數“ajaxRead”現在還沒定義。所以如果你要檢驗上面的範例程式碼,你會得到一個javascript錯誤。讓我們繼續並定義這個函數(還有其他的),讓你能夠看到ajax是如何工作的,下面的指令碼要放到你的head標籤裡:
<script type="text/javascript"><!--
function ajaxRead(file){
var xmlObj = null;
if(window.XMLHttpRequest){
xmlObj = new XMLHttpRequest();
} else if(window.ActiveXObject){
xmlObj = new ActiveXObject("Microsoft.XMLHTTP");
} else {
return;
}
xmlObj.onreadystatechange = function(){
if(xmlObj.readyState == 4){
updateObj('xmlObj', xmlObj.responseXML.getElementsByTagName('data')[0].firstChild.data);
}
}
xmlObj.open ('GET', file, true);
xmlObj.send ('');
}
function updateObj(obj, data){
document.getElementById(obj).firstChild.data = data;
}
//--></script>
這堆代碼有點多,讓我們一點點的進行。第一個函數叫做“ajaxRead”-也就是我們在頁面的“查看XML資料”連結中調用的函數,我們定義了一個“xmlObj”變數-這將作為用戶端(使用者正在查看的這個web頁面)以及服務端(web網站本身)之間的中介軟體。我們在一個if/else塊中定義這個對象:
if(window.XMLHttpRequest){
xmlObj = new XMLHttpRequest();
} else if(window.ActiveXObject){
xmlObj = new ActiveXObject("Microsoft.XMLHTTP");
} else {
return;
}
這隻是一個對不同對象是否可用的測試-某些瀏覽器實現了不同的XMLHttpRequest對象,所以當我們定義“xmlObj”作為我們的XMLHttpRequest對象時,我們不得不根據瀏覽器所實現的來定義它。如果沒有可用的XMLHttpRequest對象,我們將執行“return”語句結束這個函數以避免指令碼錯誤。在大部分情況下,這個檢驗將返回一個XMLHttpRequest對象-這部分代碼應該能夠在絕大部分的瀏覽器上工作,除了少部分比較老的瀏覽器的異常情況(它能夠工作在ie5.01上,但是在netscape4上會使函數終止)。
接下來是這些代碼塊:
xmlObj.onreadystatechange = function(){
if(xmlObj.readyState == 4){
updateObj('xmlObj', xmlObj.responseXML.getElementsByTagName('data')[0].firstChild.data);
}
}
每次XMLHttpRequest的狀態發生變化,事件“onreadystatechange”就會被觸發。通過使用“xmlObj.onreadystatechange = function(){...}”我們能夠建立一個函數並讓它在這個XMLHttpRequest對象的狀態每次發生改變的時候立刻運行。這裡總共有五個狀態,由0走到4。
0 – 尚未初始化(在這個XMLHttpRequest開始前)
1 – 載入(XMLHttpRequest初始化一結束)
2 – 載入結束(XMLHttpRequest一從伺服器上獲得一個回應)
3 – 互動(當XMLHttpRequest對象和伺服器串連中)
4 – 結束(當XMLHttpRequest被告知它已經完成了所有人物並結束運行)
這第五個狀態(數字4)就是我們能夠確定資料已經可用的標誌,所以我們檢驗這個xmlObj.readyState是否等於“4”來確定資料是否可用,如果是4,我們運行updateObj函數。這個函數帶兩個參數:一個當前web頁面的元素ID(當前web頁面中要更新的元素)以及用於填充這個元素的資料。這個函數的運行方式在稍後將更詳細地解釋。
我們的web頁面的p元素有一個id“xmlData”,這就是我們準備更新的段落。我們正在取得的資料來自於XML檔案,但它有點複雜。這裡是它如何工作的原理。
xmlObj.responseXML屬性是一個DOM對象 - 它很象“document”對象,除了它來自遠端XML檔案。換句話說,如果你在data.xml中運行指令碼,那xmlObj.responseXML就是一個“document”對象。因為我們知道這些,我們能夠通過“getElementsByTagName”方法取得任何XML節點。資料包含在一個命名為“<data>”的XML節點中,所以我們的任務很簡單:取得第一個(而且只有這一個)資料節點。因而,xmlObject.responseXML.getElementsByTagName("data")[0]返回XML檔案中的第一個<data>節點。
注意:它返回的是XML節點,而不是節點中的資料-這個資料必須通過訪問XML節點的屬性取得,這就是下一步要說的。
接下來,取得資料只需要簡單的指定“firstChild.data”(firstChild指向了那個被<data>節點包含的文本節點,而這個“data”屬性則是這個文本節點的實際文本)。
xmlObj.open ('GET', file, true);
xmlObj.send ('');
這是我們的ajaxRead函數的最後一個部分。它說了些什嗎?嗯,xmlObj的這個“open”方法開啟了一個到伺服器(通過一個指定的協議,這裡指定的是“GET”-你可以使用“USE”或者其他別的協議)的串連,去請求一個檔案(在我們的例子裡,變數“file”被作為一個參數賦給ajaxRead函數-data.xml),而且javascript可以同步(false)或者非同步(true,預設值)的處理請求。由於這是非同步Javascript和XML(AJAX),我們將使用預設的非同步方式-在這個例子中,使用同步方式將不起作用。
這是我們函數中的最後一行,它簡單的發送一個Null 字元串回伺服器。如果沒有這行,xmlObj的readyState永遠不會到4,所以你的頁面永遠不會更新。這個send方法能夠用於作其他事情,但今天我只是用來從伺服器上取得資料-並不發送它-所以在這篇文章中我不準備介入任何關於send方法的細節。
function updateObj(obj, data){
document.getElementById(obj).firstChild.data = data;
}
現在再稍微解釋一下updateObj函數:這個函數使用一個新的值來更新當前頁面上任何指定的元素。他的第一個參數,“obj”是當前頁面中元素的ID-那個要被更新的對象;它的第二個參數,“data”是用來將那個將被替換值的對象(“obj”)的內容替換掉。一般來說,檢驗一下並確定當前頁面上確實有一個元素的ID是“obj”是比較明智的,但對我們的指令碼的這個隔離等級來說校正並不必要。這個函數更新的方式和我們之前從XML檔案的“data”節點取得資料的方式類似-它定位它要更新的元素(這時候這個元素的ID代替了它的標籤名和在頁面中的索引)並設定這個元素的第一個子節點(文本節點)的data屬性為新的值。如果你需要使用HTML而不是純文字來更新一個元素,你也可以使用
document.getElementById(obj).innerHTML = data
這就是全部了
這個概念很簡單,而且代碼也不是很難。你能夠從某個地方讀取一個檔案並且不需要重新載入這個web頁面。你有足夠的靈活性來作各種事情,包括從表單發送資料(不需要重新載入web頁面)並且使用一個服務端語言來動態產生XML檔案。如果你需要更近一步,記得這個串連是很有用的-哦,還要記得Google是你朋友。在另外的文章中,我將解釋你如何配合服務端技術使用AJAX來構造強大的web應用程式。
關於作者
Jonathan Fenocchi(mail:jona#slightlyremarkable.com #換成@)是一個網路開發人員,主攻web設計,用戶端指令碼,php指令碼。
他的網站位於:http://www.slightlyremarkable.com