這篇文章將帶您瀏覽整個AJAX的基本概貌,并展示兩個簡單的例子讓您輕松上路.?
什么是?AJAX?? AJAX?(異步?JavaScript?和?XML)?是個新產(chǎn)生的術(shù)語,專為描述JavaScript的兩項(xiàng)強(qiáng)大性能.這兩項(xiàng)性能在多年來一直被網(wǎng)絡(luò)開發(fā)者所忽略,直到最近Gmail,?Google?suggest和google?Maps的橫空出世才使人們開始意識到其重要性.?
這兩項(xiàng)被忽視的性能是:? 無需重新裝載整個頁面便能向服務(wù)器發(fā)送請求.? 對XML文檔的解析和處理.
步驟?1???"請!"?---?如何發(fā)送一個HTTP請求
為了用JavaScript向服務(wù)器發(fā)送一個HTTP請求,?需要一個具備這種功能的類實(shí)例.?這樣的類首先由Internet?Explorer以ActiveX對象引入,?被稱為XMLHTTP.?后來Mozilla,?Safari?和其他瀏覽器紛紛仿效,?提供了XMLHttpRequest類,它支持微軟的ActiveX對象所提供的方法和屬性.?
因此,?為了創(chuàng)建一個跨瀏覽器的這樣的類實(shí)例(對象),?可以應(yīng)用如下代碼:?
if?(window.XMLHttpRequest)?{?//?Mozilla,?Safari,?... ????http_request?=?new?XMLHttpRequest(); }?else?if?(window.ActiveXObject)?{?//?IE ????http_request?=?new?ActiveXObject("Microsoft.XMLHTTP"); }
(上例對代碼做了一定簡化,這是為了解釋如何創(chuàng)建XMLHTTP類實(shí)例.?實(shí)際的代碼實(shí)例可參閱本篇步驟3.)?
如果服務(wù)器的響應(yīng)沒有XML?mime-type?header,某些Mozilla瀏覽器可能無法正常工作.?為了解決這個問題,?如果服務(wù)器響應(yīng)的header不是text/xml,可以調(diào)用其它方法修改該header.?
http_request?=?new?XMLHttpRequest(); http_request.overrideMimeType('text/xml');
接下來要決定當(dāng)收到服務(wù)器的響應(yīng)后,需要做什么.這需要告訴HTTP請求對象用哪一個JavaScript函數(shù)處理這個響應(yīng).可以將對象的onreadystatechange屬性設(shè)置為要使用的JavaScript的函數(shù)名,如下所示:?
http_request.onreadystatechange?=?nameOfTheFunction;?
注意:在函數(shù)名后沒有括號,也無需傳遞參數(shù).另外還有一種方法,可以在扉頁(fly)中定義函數(shù)及其對響應(yīng)要采取的行為,如下所示:?
http_request.onreadystatechange?=?function(){ ????//?do?the?thing };
在定義了如何處理響應(yīng)后,就要發(fā)送請求了.可以調(diào)用HTTP請求類的open()和send()方法,?如下所示:?
http_request.open('GET',?'http://www.example.org/some.file',?true); http_request.send(null);
open()的第一個參數(shù)是HTTP請求方式???GET,?POST,?HEAD?或任何服務(wù)器所支持的您想調(diào)用的方式.?按照HTTP規(guī)范,該參數(shù)要大寫;否則,某些瀏覽器(如Firefox)可能無法處理請求.有關(guān)HTTP請求方法的詳細(xì)信息可參考http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html?W3C?specs? 第二個參數(shù)是請求頁面的URL.由于自身安全特性的限制,該頁面不能為第三方域名的頁面.同時一定要保證在所有的頁面中都使用準(zhǔn)確的域名,否則調(diào)用open()會得到"permission?denied"的錯誤提示.一個常見的錯誤是訪問站點(diǎn)時使用domain.tld,而當(dāng)請求頁面時,卻使用www.domain.tld.? 第三個參數(shù)設(shè)置請求是否為異步模式.如果是TRUE,?JavaScript函數(shù)將繼續(xù)執(zhí)行,而不等待服務(wù)器響應(yīng).這就是"AJAX"中的"A".? 如果第一個參數(shù)是"POST",send()方法的參數(shù)可以是任何想送給服務(wù)器的數(shù)據(jù).?這時數(shù)據(jù)要以字符串的形式送給服務(wù)器,如下所示:?
name=value&anothername=othervalue&so=on?
步驟?2???"收到!"?---?處理服務(wù)器的響應(yīng)?
當(dāng)發(fā)送請求時,要提供指定處理響應(yīng)的JavaScript函數(shù)名.?
http_request.onreadystatechange?=?nameOfTheFunction;?
我們來看看這個函數(shù)的功能是什么.首先函數(shù)會檢查請求的狀態(tài).如果狀態(tài)值是4,就意味著一個完整的服務(wù)器響應(yīng)已經(jīng)收到了,您將可以處理該響應(yīng).?
if?(http_request.readyState?==?4)?{ ????//?everything?is?good,?the?response?is?received }?else?{ ????//?still?not?ready }
readyState的取值如下:? 0?(未初始化)? 1?(正在裝載)? 2?(裝載完畢)? 3?(交互中)? 4?(完成)?
接著,函數(shù)會檢查HTTP服務(wù)器響應(yīng)的狀態(tài)值.?完整的狀態(tài)取值可參見?W3C?site.?我們著重看值為200?OK的響應(yīng).?
if?(http_request.status?==?200)?{ ????//?perfect! }?else?{ ????//?there?was?a?problem?with?the?request, ????//?for?example?the?response?may?be?a?404?(Not?Found) ????//?or?500?(Internal?Server?Error)?response?codes }
在檢查完請求的狀態(tài)值和響應(yīng)的HTTP狀態(tài)值后,?您就可以處理從服務(wù)器得到的數(shù)據(jù)了.有兩種方式可以得到這些數(shù)據(jù):?
http_request.responseText???以文本字符串的方式返回服務(wù)器的響應(yīng)? http_request.responseXML???以XMLDocument對象方式返回響應(yīng).處理XMLDocument對象可以用JavaScript?DOM函數(shù)?
步驟?3???"萬事俱備!"?-?簡單實(shí)例
我們現(xiàn)在將整個過程完整地做一次,發(fā)送一個簡單的HTTP請求.?我們用JavaScript請求一個HTML文件,?test.html,?文件的文本內(nèi)容為"I'm?a?test.".然后我們"alert()"test.html文件的內(nèi)容.?
<script?type="text/javascript"?language="javascript"> ????var?http_request?=?false; ????function?makeRequest(url)?{
????????http_request?=?false;
????????if?(window.XMLHttpRequest)?{?//?Mozilla,?Safari,... ????????????http_request?=?new?XMLHttpRequest(); ????????????if?(http_request.overrideMimeType)?{ ????????????????http_request.overrideMimeType('text/xml'); ????????????} ????????}?else?if?(window.ActiveXObject)?{?//?IE ????????????try?{ ????????????????http_request?=?new?ActiveXObject("Msxml2.XMLHTTP"); ????????????}?catch?(e)?{ ????????????????try?{ ????????????????????http_request?=?new?ActiveXObject("Microsoft.XMLHTTP"); ????????????????}?catch?(e)?{} ????????????} ????????}
????????if?(!http_request)?{ ????????????alert('Giving?up?:(?Cannot?create?an?XMLHTTP?instance'); ????????????return?false; ????????} ????????http_request.onreadystatechange?=?alertContents; ????????http_request.open('GET',?url,?true); ????????http_request.send(null);
????}
????function?alertContents()?{
????????if?(http_request.readyState?==?4)?{ ????????????if?(http_request.status?==?200)?{ ????????????????alert(http_request.responseText); ????????????}?else?{ ????????????????alert('There?was?a?problem?with?the?request.'); ????????????} ????????}
????} </script> <span ????style="cursor:?pointer;?text-decoration:?underline" ????onclick="makeRequest('test.html')"> ????????Make?a?request </span>
本例中:? 用戶點(diǎn)擊瀏覽器上的"請求"鏈接;? 接著函數(shù)makeRequest()將被調(diào)用.其參數(shù)???HTML文件test.html在同一目錄下;? 這樣就發(fā)起了一個請求.onreadystatechange的執(zhí)行結(jié)果會被傳送給alertContents();? alertContents()將檢查服務(wù)器的響應(yīng)是否成功地收到,如果是,就會"alert()"test.html文件的內(nèi)容.?
步驟?4???"X-文檔"?---?處理XML響應(yīng)
在前面的例子中,當(dāng)服務(wù)器對HTTP請求的響應(yīng)被收到后,我們會調(diào)用請求對象的reponseText屬性.該屬性包含了test.html文件的內(nèi)容.現(xiàn)在我們來試試responseXML屬性.?
首先,我們新建一個有效的XML文件,后面我們將使用這個文件.該文件(test.xml)源代碼如下所示:?
<?xml?version="1.0"??> <root> ????I'm?a?test. </root>
在該腳本中,我們只需修改請求部分:?
... onclick="makeRequest('test.xml')"> ...
接著,在alertContents()中,我們將alert()的代碼alert(http_request.responseText);換成:?
var?xmldoc?=?http_request.responseXML; var?root_node?=?xmldoc.getElementsByTagName('root').item(0); alert(root_node.firstChild.data);
這里,我們使用了responseXML提供的XMLDocument對象并用DOM方法獲取存于XML文件中的內(nèi)容.?
|
|