AJAX即“Asynchronous JAVAScript and XML”(非同步的JavaScript與XML技術(shù)),指的是一套綜合了多項技術(shù)的瀏覽器端網(wǎng)頁開發(fā)技術(shù)。Ajax的概念由杰西·詹姆士·賈瑞特所提出。
傳統(tǒng)的Web應(yīng)用允許用戶端填寫表單(form),當(dāng)送出表單時就向網(wǎng)頁伺服器發(fā)送一個請求。伺服器接收并處理傳來的表單,然后送回一個新的網(wǎng)頁,但這個做法浪費了許多帶寬,因為在前后兩個頁面中的大部分html碼往往是相同的。由于每次應(yīng)用的溝通都需要向伺服器發(fā)送請求,應(yīng)用的回應(yīng)時間依賴于伺服器的回應(yīng)時間。這導(dǎo)致了用戶界面的回應(yīng)比本機應(yīng)用慢得多。
與此不同,AJAX應(yīng)用可以僅向伺服器發(fā)送并取回必須的數(shù)據(jù),并在客戶端采用JavaScript處理來自伺服器的回應(yīng)。因為在伺服器和瀏覽器之間交換的數(shù)據(jù)大量減少,伺服器回應(yīng)更快了。同時,很多的處理工作可以在發(fā)出請求的客戶端機器上完成,因此Web伺服器的負(fù)荷也減少了。
類似于DHTML或LAMP,AJAX不是指一種單一的技術(shù),而是有機地利用了一系列相關(guān)的技術(shù)。雖然其名稱包含XML,但實際上數(shù)據(jù)格式可以由JSON代替,進一步減少數(shù)據(jù)量,形成所謂的AJAJ。而客戶端與服務(wù)器也并不需要異步。一些基于AJAX的“派生/合成”式(derivative/composite)的技術(shù)也正在出現(xiàn),如AFLAX。
20世紀(jì)90年代,幾乎所有的網(wǎng)站都由HTML頁面實現(xiàn),服務(wù)器處理每一個用戶請求都需要重新加載網(wǎng)頁。這樣的處理方式效率不高。用戶的體驗是所有頁面都會消失,再重新載入,即使只是一部分頁面元素改變也要重新載入整個頁面,不僅要刷新改變的部分,連沒有變化的部分也要刷新。這會加重服務(wù)器的負(fù)擔(dān)。
這可以用異步加載來解決。1995年,JAVA語言的第一版發(fā)布,隨之發(fā)布的的Java Applets(JAVA小程序)首次實現(xiàn)了異步加載。瀏覽器通過運行嵌入網(wǎng)頁中的Java applets與服務(wù)器交換數(shù)據(jù),不必刷新網(wǎng)頁。1996年,Internet Explorer將iframe元素加入到HTML,支持局部刷新網(wǎng)頁。
1998年前后,Outlook Web Access小組寫成了允許客戶端腳本發(fā)送HTTP請求(XMLHTTP)的第一個組件。該組件原屬于微軟Exchange Server,并且迅速地成為了Internet Explorer 4.0[2]的一部分。部分觀察家認(rèn)為,Outlook Web Access是第一個應(yīng)用了Ajax技術(shù)的成功的商業(yè)應(yīng)用程序,并成為包括Oddpost的網(wǎng)絡(luò)郵件產(chǎn)品在內(nèi)的許多產(chǎn)品的領(lǐng)頭羊。但是,2005年初,許多事件使得Ajax被大眾所接受。google在它著名的交互應(yīng)用程序中使用了異步通訊,如Google討論組、Google地圖、Google搜索建議、Gmail等。Ajax這個詞由《Ajax: A New Approach to Web Applications》一文所創(chuàng),該文的迅速流傳提高了人們使用該項技術(shù)的意識。另外,對Mozilla/Gecko的支持使得該技術(shù)走向成熟,變得更為簡單易用。
使用Ajax的最大優(yōu)點,就是能在不更新整個頁面的前提下維護數(shù)據(jù)。這使得Web應(yīng)用程序更為迅捷地回應(yīng)用戶動作,并避免了在網(wǎng)絡(luò)上發(fā)送那些沒有改變的信息。
Ajax不需要任何瀏覽器插件,但需要用戶允許JavaScript在瀏覽器上執(zhí)行。就像DHTML應(yīng)用程序那樣,Ajax應(yīng)用程序必須在眾多不同的瀏覽器和平臺上經(jīng)過嚴(yán)格的測試。隨著Ajax的成熟,一些簡化Ajax使用方法的程序庫也相繼問世。同樣,也出現(xiàn)了另一種輔助程序設(shè)計的技術(shù),為那些不支持JavaScript的用戶提供替代功能。
對應(yīng)用Ajax最主要的批評就是,它可能破壞瀏覽器的后退與加入收藏書簽功能。
在動態(tài)更新頁面的情況下,用戶無法回到前一個頁面狀態(tài),這是因為瀏覽器僅能記下歷史記錄中的靜態(tài)頁面。一個被完整讀入的頁面與一個已經(jīng)被動態(tài)修改過的頁面之間的可能差別非常微妙;用戶通常都希望單擊后退按鈕,就能夠取消他們的前一次操作,但是在Ajax應(yīng)用程序中,卻無法這樣做。不過開發(fā)者已想出了種種辦法來解決這個問題,HTML5 之前的方法大多是在用戶單擊后退按鈕訪問歷史記錄時,通過建立或使用一個隱藏的IFRAME來重現(xiàn)頁面上的變更。(例如,當(dāng)用戶在Google Maps中單擊后退時,它在一個隱藏的IFRAME中進行搜索,然后將搜索結(jié)果反映到Ajax元素上,以便將應(yīng)用程序狀態(tài)恢復(fù)到當(dāng)時的狀態(tài))。
關(guān)于無法將狀態(tài)加入收藏或書簽的問題,HTML5之前的一種方式是使用URL片斷標(biāo)識符(通常被稱為錨點,即URL中#后面的部分)來保持追蹤,允許用戶回到指定的某個應(yīng)用程序狀態(tài)。(許多瀏覽器允許JavaScript動態(tài)更新錨點,這使得Ajax應(yīng)用程序能夠在更新顯示內(nèi)容的同時更新錨點。)HTML5 以后可以直接操作瀏覽歷史,并以字串形式儲存網(wǎng)頁狀態(tài),將網(wǎng)頁加入網(wǎng)頁收藏夾或書簽時狀態(tài)會被隱形地保留。上述兩個方法也可以同時解決無法后退的問題。
進行Ajax開發(fā)時,網(wǎng)絡(luò)延遲——即用戶發(fā)出請求到服務(wù)器發(fā)出響應(yīng)之間的間隔——需要慎重考慮。如果不給予用戶明確的回應(yīng)[4],沒有恰當(dāng)?shù)念A(yù)讀數(shù)據(jù)[5],或者對XMLHttpRequest的不恰當(dāng)處理[6],都會使用戶感到厭煩[7]。通常的解決方案是,使用一個可視化的組件來告訴用戶系統(tǒng)正在進行后臺操作并且正在讀取數(shù)據(jù)和內(nèi)容。
對程序員而言,開發(fā)Ajax應(yīng)用最頭痛的問題莫過于以下幾點:
Ajax在本質(zhì)上是一個瀏覽器端的技術(shù),首先面臨無可避免的第一個問題即是瀏覽器的兼容性問題。各家瀏覽器對JavaScript/DOM/css的支持總有部分不太相同或是有Bug,甚至同一瀏覽器的各個版本間對于JavaScript/DOM/CSS的支持也有可能部分不一樣。這導(dǎo)致程序員在寫Ajax應(yīng)用時花大部分的時間在調(diào)試瀏覽器的兼容性而非在應(yīng)用程序本身。因此,目前大部分的Ajax鏈接庫或開發(fā)框架大多以js鏈接庫的形式存在,以定義更高階的JavaScript API、JavaScript對象(模板)、或者JavaScript Widgets來解決此問題。如prototype.js。
Ajax技術(shù)之主要目的在于局部交換客戶端及服務(wù)器之間的數(shù)據(jù)。如同傳統(tǒng)之主從架構(gòu),無可避免的會有部分的業(yè)務(wù)邏輯會實現(xiàn)在客戶端,或部分在客戶端,部分在服務(wù)器。由于業(yè)務(wù)邏輯可能分散在客戶端及服務(wù)器,且以不同之程序語言實現(xiàn),這導(dǎo)致Ajax應(yīng)用程序極難維護。如有使用者接口或業(yè)務(wù)邏輯之更動需求,再加上前一個JavaScript/DOM/CSS之兼容性問題,Ajax應(yīng)用往往變成程序員的夢魘。針對業(yè)務(wù)邏輯分散的問題,Ajax開發(fā)框架大致可分為兩類:
將業(yè)務(wù)邏輯及表現(xiàn)層放在瀏覽器,數(shù)據(jù)層放在服務(wù)器:因為所有的程序以JavaScript執(zhí)行在客戶端,只有需要數(shù)據(jù)時才向服務(wù)器要求服務(wù),此法又稱為胖客戶端(fat client)架構(gòu)。服務(wù)器在此架構(gòu)下通常僅用于提供及儲存數(shù)據(jù)。此法的好處在于程序員可以充分利用JavaScript搭配業(yè)務(wù)邏輯來做出特殊的使用者接口,以符合終端使用者的要求。但是問題也不少,主因在第一,JavaScript語言本身之能力可能不足以處理復(fù)雜的業(yè)務(wù)邏輯。第二,JavaScript的執(zhí)行效能一向不好。第三,JavaScript存取服務(wù)器數(shù)據(jù),仍需適當(dāng)?shù)姆?wù)器端程序之配合。第四,瀏覽器兼容性的問題又出現(xiàn)。有些Ajax開發(fā)框架如DWR企圖以自動生成JavaScript之方式來避免兼容的問題,并開立通道使得JavaScript可以直接叫用服務(wù)器端的Java程序來簡化數(shù)據(jù)的存取。但是前述第一及第二兩個問題仍然存在,程序員必須費相當(dāng)?shù)牧獠拍苓_到應(yīng)用程序之規(guī)格要求,或可能根本無法達到要求。
將表現(xiàn)層、業(yè)務(wù)邏輯、及數(shù)據(jù)層放在服務(wù)器,瀏覽器僅有使用者接口引擎(User Interface engine);此法又稱為瘦客戶端(thin client)架構(gòu),或中心服務(wù)器(server-centric)架構(gòu)。瀏覽器的使用者接口引擎僅用于反映服務(wù)器的表現(xiàn)層以及傳達使用者的輸入回到服務(wù)器的表現(xiàn)層。由瀏覽器所觸發(fā)之事件亦送回服務(wù)器處理,根據(jù)業(yè)務(wù)邏輯來更新表現(xiàn)層,然后反映回瀏覽器。因為所有應(yīng)用程序完全在服務(wù)器執(zhí)行,數(shù)據(jù)及表現(xiàn)層皆可直接存取,程序員只需使用服務(wù)器端相對較成熟之程序語言(如Java語言)即可,不需再學(xué)習(xí)JavaScript/DOM/CSS,在開發(fā)應(yīng)用程序時相對容易。缺點在于使用者接口引擎以及表現(xiàn)層通常以標(biāo)準(zhǔn)組件的形式存在,如需要特殊組件(使用者接口)時,往往須待原框架之開發(fā)者提供,緩不濟急。如開源碼Ajax開發(fā)框架ZK目前支持XUL及XHTML組件,尚無XAML之支持。
JavaScript編程的最大問題來自不同的瀏覽器對各種技術(shù)和標(biāo)準(zhǔn)的支持。
XmlHttpRequest對象在不同瀏覽器中不同的創(chuàng)建方法,以下是跨瀏覽器的通用方法:
// Provide the XMLHttpRequest class for IE 5.x-6.x:
// Other browsers (including IE 7.x-8.x) ignore this
// when XMLHttpRequest is predefined
var xmlHttp;
if (typeof XMLHttpRequest != "undefined") {
xmlHttp = new XMLHttpRequest();
} else if (window.ActiveXObject) {
var aVersions = ["Msxml2.XMLHttp.5.0", "Msxml2.XMLHttp.4.0", "Msxml2.XMLHttp.3.0", "Msxml2.XMLHttp", "Microsoft.XMLHttp"];
for (var i = 0; i < aVersions.length; i++) {
try {
xmlHttp = new ActiveXObject(aVersions[i]);
break;
} catch (e) {}
}
}
參考鏈接:
https://zh.wikipedia.org/zh-hans/AJAX






