Ajax(Asynchronous JavaScript and XML)是一系列web開發(fā)技術(shù)的集合,使用很多的web技術(shù)在客戶端開發(fā)異步web應(yīng)用。利用Ajax,web應(yīng)用可以異步的發(fā)送數(shù)據(jù)獲取數(shù)據(jù),而不干擾現(xiàn)有頁面的顯示和行為。通過解耦數(shù)據(jù)接口層和展現(xiàn)層,Ajax允許web頁面或者其他擴展的web應(yīng)用動態(tài)的改變數(shù)據(jù)而不用重新加載整個頁面。實現(xiàn)通常選擇JSON代替XML,因為更接近JavaScript。
Ajax不是一種技術(shù),是一組技術(shù)。HTML和CSS用來組合標記和樣式信息。用戶可以利用js訪問DOM對象負責動態(tài)展示。js和XMLHttpRequest對象提供一種瀏覽器和服務(wù)端異步互換數(shù)據(jù)的方法從而避免整個頁面加載。
歷史
在90年代中期,許多web站點完全基于html頁面。每個用戶行為都需要從服務(wù)端重新加載頁面。這個過程很不方便,影響用戶體驗:所有的頁面內(nèi)容消失,然后又出現(xiàn)。每次因為小部分改動需要瀏覽器重新加載頁面,所有內(nèi)容都必須重新獲取,甚至只有很少的信息改變。這會額外增加服務(wù)端負載,浪費帶寬,影響性能。
在1996年,IE引入了iframe標簽來異步加載獲取內(nèi)容。
在1998年,微軟的郵件組團隊利用客戶端腳本實現(xiàn)了第一個XMLHTTP組件。
在1999年,微軟在IE的默認頁面使用iframe技術(shù)動態(tài)更新新聞故事和股票行情,并且在IE5中創(chuàng)建了XMLHTTP ActiveX組件,這個技術(shù)隨后被Mozilla,Safari,Opera以及其他瀏覽器采用,作為XMLHttpRequest js對象。微軟在IE7中采用了原生的XMLHttpRequest模塊。IE仍然支持ActiveX版本,但是在Edge中不支持了。這種技術(shù)的使用在當時相當不明朗直到出現(xiàn)在大規(guī)模線上應(yīng)用中,比如Outlook Web App (2000)和Oddpost。
谷歌在Gmail(2004)和Google Maps(2005)中廣發(fā)部署了符合標準的跨瀏覽器Ajax。在2004年10月Kayak.com的公測版本是首次大規(guī)模電子商務(wù)網(wǎng)站使用了他們當時稱為"the xml htpp thing"的技術(shù)。
Jesse James Garrett在2005年2月18號發(fā)表的一篇題為"Ajax: A New Approach to Web Applications"的論文中,基于Google 頁面中使用的技術(shù),公開闡明了"Ajax"這個術(shù)語。
在2006年4月5號,W3C發(fā)表了第一個關(guān)于XMLHttpRequest對象的草案,嘗試建立一個官方的Web標準。關(guān)于XMLHttpRequest對象最新的草案是在2014年1月30號發(fā)布的。
技術(shù)集
Ajax術(shù)語已經(jīng)變成了web應(yīng)用用來與服務(wù)端在幕后交流不打斷頁面當前狀態(tài)而使用的一組技術(shù)的代表。在Jesse James Garrett的論文里創(chuàng)造的Ajax術(shù)語包括以下技術(shù):
- 展現(xiàn)層的HTML(或者XHTML)和CSS
- 動態(tài)顯示和與數(shù)據(jù)交互的DOM對象
- 為了交換數(shù)據(jù)的JOSN或者XML,為了操縱數(shù)據(jù)的XSLT
- 為了異步通信的XMLHttpRequest對象
- 把這些技術(shù)整合起來的JavaScript
從那以后,Ajax應(yīng)用使用的技術(shù)已經(jīng)有了很大的發(fā)展,包括Ajax術(shù)語的定義。數(shù)據(jù)交換不再需要XML,操縱數(shù)據(jù)也不再需要XSLT了。JOSN經(jīng)常被使用作為數(shù)據(jù)交換的一種格式,盡管其他的格式例如預(yù)定義的HTML或者純文本仍然可以使用。
Asynchronous HTML and HTTP(AHAH)使用XMLHttpRequest對象獲取(X)HTML片段,然后插入到Web頁面中。
弊端
- 如果用戶瀏覽器不支持JavaScript或者XMLHttpRequest,或者禁用這種功能,則不能正常使用依賴Ajax的頁面。簡單設(shè)備(例如智能手機,pad)可能不支持需要的這些技術(shù)。讓用戶使用這種功能的唯一方法是回退到?jīng)]有JavaScript方法??梢酝ㄟ^確保鏈接表單正確解析而不是僅僅依賴Ajax來實現(xiàn)相關(guān)功能。
- 同樣的,一些使用Ajax的Web應(yīng)用對屏幕閱讀技術(shù)不友好,例如JAWS。WAI-ARIA標準提供了一種方法在這種情況下提供提示。
- 屏幕閱讀器可以使用Ajax,但是也可能不能正確的讀取動態(tài)產(chǎn)生的內(nèi)容。
- 同源策略阻止了一些Ajax技術(shù)跨域使用,盡管W3C有關(guān)于XMLHttpRequest對象的草案允許這個功能。通過使用一個特別的跨域通道例如頁面中的iframe或者使用JSONP可以跨過這種安全限制。
- 異步的回調(diào)編程可能導(dǎo)致負責的代碼難以維護,調(diào)試和測試。
- 因為Ajax的異步特性,客戶端發(fā)送接收到每塊數(shù)據(jù)都發(fā)生在專門為改事件建立的連接上。這就為每個行為增加一種需要,那就是客戶端必須輪詢服務(wù)端,而不是監(jiān)聽,這就會導(dǎo)致額外開銷。這種開銷會導(dǎo)致Ajax應(yīng)用有更高的延遲相比于利用websocket技術(shù)獲取數(shù)據(jù)。
- 在非HTML5瀏覽器中,使用Ajax請求創(chuàng)建的動態(tài)頁面不能自動的注冊到瀏覽器的歷史記錄中,所以在點擊瀏覽器"回退"按鈕時,瀏覽器不會回到Ajax發(fā)生之前的狀態(tài),但是會回退到上次訪問的頁面。這種在頁面之間導(dǎo)航而不是在頁面狀態(tài)之間導(dǎo)航的行為可能不是想要的,但是如果需要追蹤頁面狀態(tài),那么對于非HTML5的瀏覽器一個變通的方案就是使用非透明的iframe觸發(fā)瀏覽器歷史記錄的改變。另一個變通方法就是利用Ajax技術(shù)更改URL的片段標識符(URL中在"#"之后的部分)。HTML5提供了一個擴展的API標準來操作瀏覽器歷史記錄。
- 動態(tài)web頁面更新導(dǎo)致很難記標簽,返回應(yīng)用的特性狀態(tài)。這種問題的解決辦法也是存在的,也是利用URL的片段標識符。HTML5提供了解決上面問題的方法。
- 由于Ajax應(yīng)用的特性,動態(tài)頁面更新可能會打斷用戶交互,特別是當網(wǎng)絡(luò)連接很慢或者不可能的時候。例如,編輯一個搜索框可能會觸發(fā)一個服務(wù)端查詢,但是用戶可能不知道查詢結(jié)束時會彈出一個框,如果此時網(wǎng)絡(luò)很慢,彈窗可能會在一個不恰當?shù)臅r候彈出,當用戶已經(jīng)開始處理其他的事情時。
- 除了Google,大多數(shù)網(wǎng)絡(luò)爬蟲不能執(zhí)行js代碼,所以為了被搜索引擎收錄,Web應(yīng)用必須為那些通過Ajax獲取內(nèi)容的頁面提供一個備選頁面。
例子
下面就是一個簡單的使用GET方法進行Ajax請求的例子
get-ajax-data.js:
var xhr = new XMLHttpRequest();
xhr.open('get', 'send-ajax-data.php');
xhr.onreadystatechange = function () {
var DONE = 4;
var OK = 200;
if (xhr.readyState === DONE) {
if (xhr.status === OK) {
alert(xhr.responseText);
} else {
alert('Error: ' + xhr.status);
}
}
};
xhr.send(null);
send-ajax-data.php:
header('Content-Type: text/plain');
echo "This is the returned text.";
jQuery示例
使用流行的jQuery庫,完成上例中相同的事情
$.get('send-ajax-data.php')
.done(function(data) {
alert(data);
})
.fail(function(data) {
alert('Error: ' + data);
});
做好前端開發(fā)必須對HTTP的相關(guān)知識有所了解,所以我創(chuàng)建了一個專題前端必備HTTP技能專門收集前端相關(guān)的HTTP知識,歡迎關(guān)注,投稿。
PS:本文翻譯自維基百科,原文地址https://en.wikipedia.org/wiki/Ajax_(programming)