# 詳細解釋什麼是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 應用程式便能快速、即時更動介面及內容,不需要重新讀取整個網頁,讓程式更快回應使用者的操作。

*:bulb:「AJAX」概念的命名者 - 傑西·詹姆士·賈瑞特
「Google地圖」於2005年上線後,當年2月傑西發表出一篇談論此讓網頁透過Javascript以XML格式來回傳資料、達到非同步更新網頁內容技術的文章,並將此技術以「AJAX」來簡稱。(維基百科)*
## 沒有Ajax的傳統網頁

使用**同步請求 (Synchronous request):**
1. 客戶端 (Client) 對伺服器端 (Server) 送出 Request ,並且在收到伺服器端的 Response 之後才會繼續下一步的動作,等待的期間無法處理其他事情。
2. 對照上圖來看,每一次的發送Request,瀏覽器都要重新載入整個頁面。假設頁面有100k的數據,只有1k數據需要刷新,如果使用同步載入的方式,每一次載入都會消耗100k,這樣使得瀏覽器要一次處理很多資料,造成運作速度緩慢。
## 運用Ajax的現代網頁

使用**非同步請求 (Asynchronous request):**
1. 客戶端 (Client) 向伺服器端 (Server) 送出 Request 之後,不需要等待結果,仍可以持續處理其他事情,甚至繼續送出其他 Request。
2. Responese 傳回之後,內容就被即時融合進當下頁面或應用中。這也是為什麼當我們瀏覽 Facebook、Twitter 內容時,不會看見整個網頁一直重新整理。
3. 套用剛剛的例子,假設頁面有100k的數據,使用Ajax的網頁只需要刷新1k的數據來更新局部,其餘99k的數據都不需要再重傳。
4. 使用Ajax的網頁相較於傳統網頁,它大幅度降低每次請求與回應的資料量,提高了瀏覽速度。
> **Ajax執行的特色**

* 使用 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)