# 詳細解釋什麼是Ajax? > Explain Ajax in as much detail as possible. :::info :a: jax 是 Asynchronous JavaScript and XML 的縮寫,並不是新的程式語言,是多個技術的組合,用於建立快速動態的網頁。 通過在後台與伺服器進行少量資料交換,Ajax可以使網頁實現非同步更新,也就是說可以不用重整網頁就能達到局部更新,進而減少了網頁等待時間,同時也降低了網絡流量,增強使用者體驗。 ::: ## 什麼是 Ajax? **Ajax**:非同步 JavaScript 及 XML(Asynchronous JavaScript and XML) > **A**synchronous:非同步 > **J**avaScript:使用的程式語言 > **A**nd > **X**ML:Client 與 Server 交換資料用的資料與方法,近年由於 JSON 等格式的流行,使用 Ajax 處理的資料並不限於 XML。 > [color=#3b75c6] Ajax並不能稱作是單一的「技術」,而是 2005 年時由 Jesse James Garrett 所發明的==術語==,描述一種使用數個既有技術的「新」方法。這些技術包括: * **HTML**(超文本標記語言,語法較為鬆散的、不嚴格的Web語言) * **XML**(可擴展標記語言,主要用於存儲數據和結構) * **XHTML**(可擴展超文本標記語言,基於XML,作用與HTML類似,但語法更嚴格) * **XSLT**(一種用於將 XML 文檔轉換為 XHTML 文檔或其他 XML 文檔的語言) * **CSS**(層疊樣式表) * **JavaScript** * **DOM**(文件物件模型) * **XMLHttpRequest物件**(最重要的一項,Ajax利用這個物件來向伺服器進行通訊。 它可以傳送並接收多種格式的資訊,包括JSON、XML、HTML、以及文字檔案。) :pushpin:當這些技術被結合在 Ajax 模型中,Web 應用程式便能快速、即時更動介面及內容,不需要重新讀取整個網頁,讓程式更快回應使用者的操作。 ![](https://i.imgur.com/SEHymiR.png =200x250) *:bulb:「AJAX」概念的命名者 - 傑西·詹姆士·賈瑞特 「Google地圖」於2005年上線後,當年2月傑西發表出一篇談論此讓網頁透過Javascript以XML格式來回傳資料、達到非同步更新網頁內容技術的文章,並將此技術以「AJAX」來簡稱。(維基百科)* ## 沒有Ajax的傳統網頁 ![](https://i.imgur.com/FjRU0fM.png =700x850) 使用**同步請求 (Synchronous request):** 1. 客戶端 (Client) 對伺服器端 (Server) 送出 Request ,並且在收到伺服器端的 Response 之後才會繼續下一步的動作,等待的期間無法處理其他事情。 2. 對照上圖來看,每一次的發送Request,瀏覽器都要重新載入整個頁面。假設頁面有100k的數據,只有1k數據需要刷新,如果使用同步載入的方式,每一次載入都會消耗100k,這樣使得瀏覽器要一次處理很多資料,造成運作速度緩慢。 ## 運用Ajax的現代網頁 ![](https://i.imgur.com/UDrEXph.png =650x700) 使用**非同步請求 (Asynchronous request):** 1. 客戶端 (Client) 向伺服器端 (Server) 送出 Request 之後,不需要等待結果,仍可以持續處理其他事情,甚至繼續送出其他 Request。 2. Responese 傳回之後,內容就被即時融合進當下頁面或應用中。這也是為什麼當我們瀏覽 Facebook、Twitter 內容時,不會看見整個網頁一直重新整理。 3. 套用剛剛的例子,假設頁面有100k的數據,使用Ajax的網頁只需要刷新1k的數據來更新局部,其餘99k的數據都不需要再重傳。 4. 使用Ajax的網頁相較於傳統網頁,它大幅度降低每次請求與回應的資料量,提高了瀏覽速度。 > **Ajax執行的特色** ![](https://i.imgur.com/OTvUx5Z.jpg =450x300) * 使用 JavaScript 來和 Server 通訊 * Server-side 需要運用 XHR 物件 * Server-side 的後端程式將 response 組織成XML * Response 也有其他的替代格式(Text, html tags, JSON) * 瀏覽器接收到的 Response 交給 DOM 來處理 ## Ajax 實現非同步請求的工具 **==XMLHttpRequest 物件==** * XMLHttpRequest(XHR)是原生 JS 對於 HTTP 請求的操作物件。 ``` JavaScript function sendRequest(){ // 創建 XMLHttpRequest 物件 var xhttp = new XMLHttpRequest(); // 發送 Request 給 Sever 時內容的類型 (POST時一定要設置) xhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded"); // 處理伺服器傳回的資料 xhttp.onreadystatechange = function() { // 當 readyState 等於 4(Request發送完成) 且狀態為 200("ok") 時,表示載入已就緒: if(this.readyState == 4 && this.status == 200) { document.getElementById('responseOutput').innerHTML = this.responseText; } }; // 規定 Request 的類型、URL 以及是否異步處理 Request。 xhttp.open("GET","http://www.example.org/example.txt", true); // 將 Request 發送到 Server xhttp.send(); } ``` [MDN - AJAX 相關技術的基礎](https://developer.mozilla.org/en-US/docs/Web/Guide/AJAX/Getting_Started) **==Fetch API==** * Fetch() 是 ES6 新增的 HTTP 請求方法,基於 Promise 所設計,他讓接口更簡單、簡潔、同時也避免了回調的複雜性,主要就是用來取代傳統的 XMLHttpRequest。 ```javascript // post 的範例 fetch('https://randomuser.me//admin/signin', { // 設定為 POST 請求 method: 'post', // 在 headers 加入 json 格式 headers: { 'Content-Type': 'application/json', }, // 傳送內容須轉換為字串 body: JSON.stringify({ username: 'test@gmail.com', password: '66666666', }), }) .then((response) => { return response.json(); }) .then((data) => { console.log(data); }) .catch((error) => { console.log(error); }); ``` **==Server-Sent Events==** * 傳統的網頁架構下,如果瀏覽器要持續接收來自於伺服器端的新資料時,通常都是透過 Polling、Long-Polling 或 Streaming 等方式來達成,而後來出現的 WebSocket 徹底解決了這個問題,不過除此之外,在 HTML5 標準中還有一個 Server-Sent Events 也可以處理這類型的問題。 * Server-Sent Events(簡稱 SSE)是一個已經被 W3C 納入 HTML5 標準的 API,它提供一個跨平台與瀏覽器的資料傳輸方式,可以讓伺服器主動傳送資料給瀏覽器。 * SSE 基本的概念跟 WebSocket 有點類似,瀏覽器透過 SSE 來「訂閱」伺服器上的一個資料來源,每當伺服器有新資料產生的時候,就會傳送通知訊息給瀏覽器,以便及時更新瀏覽器的網頁內容。 [HTML5 的 Server-Sent Events 介紹、串流使用教學 - G. T. Wang](https://blog.gtwang.org/web-development/stream-updates-with-server-sent-events/) [MDN - 使用 server-sent 事件](https://developer.mozilla.org/zh-TW/docs/Web/API/Server-sent_events/Using_server-sent_events) ## 延伸 - Ajax 的挑戰 [使用Ajax的挑战](http://blog.itpub.net/374079/viewspace-130000/) --- [MDN - Ajax](https://developer.mozilla.org/en-US/docs/Web/Guide/AJAX) [什麼是 Ajax? 搞懂非同步請求 (Asynchronous request)概念](https://tw.alphacamp.co/blog/ajax-asynchronous-request) [(影片)重現90年代的網頁 - The Internet As It Was In 1996 - 90's Websites](https://www.youtube.com/watch?v=ojT0gQHeyJQ) [(影片)Ajax - Introduction with Example](https://youtu.be/VTpPNIX1JXc)