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