# HTTP

### HTTP: HyperText Transfer Protocol

#### 輸入網址後瀏覽器如何運作

```

http://www.abc.com/index.html

1. 從網址解析出主機名稱
2. 使用 DNS 藉由主機名稱查詢出 IP
3. 獲得端口號 80 port
4. 建立 TCP 連接
5. client 發送請求
6. server 回應請求
7. 關閉連接

```

#### Http 0.9

```

1. 運行於 TCP/IP 上
2. 用以傳輸 HTML
3. 連接在每次請求後都會關閉

```

#### Http 1.0

```

1. 無狀態協議（Stateless Protocol）

每次的 HTTP 請求都是獨立的，伺服器不會保留客戶端的狀態資訊。每個請求/回應都沒有記憶前後的交互過程。

2. 單一請求/回應模型

HTTP 1.0 中，每個 TCP 連線只能處理一個請求與回應。伺服器在回應後就會關閉連線。這樣的設計效率較低，尤其是在網頁上有多個資源（如圖片、CSS 文件）需要請求時，會造成頻繁的連線開啟與關閉。

3. 支持不同的請求方法

支援最基本的 HTTP 請求方法：
GET：用來請求資源。
POST：用來提交數據。
HEAD：類似 GET，但只返回頭部資訊而不返回實體內容。

4. HTTP Headers

HTTP 1.0 引入了標頭（headers）機制，允許客戶端和伺服器傳送額外的元數據。例如，Content-Type 和 Content-Length 標頭用來描述回應內容的類型與大小。

5. 簡單的緩存控制

引入了基礎的緩存機制，比如 Expires 標頭來告知資源何時失效或過期，但沒有更精細的緩存控制能力（如 HTTP 1.1 中的 Cache-Control）。

6. 支援 MIME 類型

回應的內容可以使用 Content-Type 標頭來指定其 MIME 類型，這使伺服器能夠告知瀏覽器如何處理回應內容（如文字、圖像、音訊等）。

HTTP 1.0 的限制：

無法持久連接：每個請求都要建立新連接，這樣在處理多個資源時效率很低。
弱緩存機制：緩存控制較為粗糙，不能很靈活地管理客戶端的緩存。
錯誤處理有限：沒有明確定義很多常見的錯誤情況。

```

#### Http 1.1

```

1. 持久連接（Persistent Connections）

    Connection: keep-alive：HTTP 1.1 默認支持持久連接，這意味著同一個 TCP 連接可以處理多個請求和回應，不必為每次請求都重新建立連接，大大減少了連接建立的開銷，改善效能。

2. 分塊傳輸編碼（Chunked Transfer Encoding）

    支援分塊傳輸，允許伺服器分段傳輸回應內容，無需在開始傳輸前確定內容的總大小，這對於動態生成的內容非常有用。

3. 強化的緩存機制

    引入了更細緻的緩存控制標頭，如：
        Cache-Control：用來指定如何緩存和檢驗資源。
        ETag：通過資源的唯一標識符，幫助瀏覽器判斷資源是否已更改。
        If-Modified-Since 和 If-None-Match：允許客戶端在發出請求時，檢查資源是否修改過，以減少不必要的數據傳輸。

4. 支援更多請求方法

    除了 HTTP 1.0 的 GET、POST、HEAD，HTTP 1.1 增加了以下方法：
        PUT：用於上傳資源或更新已有的資源。
        DELETE：用於刪除指定的資源。
        OPTIONS：用於詢問伺服器支援的請求方法。
        TRACE：用於回顯客戶端發出的請求，主要用於診斷。

5. Host 標頭

    在 HTTP 1.1 中，Host 標頭成為強制性的，這使伺服器能夠在同一 IP 地址上托管多個網站（虛擬主機），從而允許多域名共用一個伺服器。

6. 錯誤狀態代碼擴充

    新增了更多的 HTTP 狀態碼來處理各種錯誤情況：
        100 Continue：告知客戶端請求的初始部分已接收，並可以繼續。
        409 Conflict：表示請求與伺服器的當前狀態有衝突。
        431 Request Header Fields Too Large：標頭欄位過大時返回此錯誤。

7. 內容協商（Content Negotiation）

    支援根據客戶端的需求（如語言、格式）返回不同的回應內容。例如，客戶端可使用 Accept、Accept-Language、Accept-Encoding 等標頭來指定期望的回應格式。

8. 帶寬優化

    引入了 Range 請求標頭，允許客戶端只請求部分資源（如下載檔案的一部分），大大提升了帶寬利用率和下載體驗，尤其是中斷後的續傳。

9. 更多的安全性考量

    雖然 HTTP 1.1 本身沒有引入加密機制，但它的擴展標準（如 HTTPS）則通過與 SSL/TLS 的結合來實現安全的傳輸層加密。

10. 提升了錯誤處理和診斷能力

    HTTP 1.1 引入了更完善的錯誤診斷工具，讓開發者能更輕鬆地排查問題，像 TRACE 方法可以幫助偵錯，OPTIONS 可以查詢伺服器的支持功能。

11. 管道傳送
在 HTTP 中，「管道傳送」(HTTP Pipelining) 是一種技術，允許客戶端在尚未收到前一個請求的回應之前，連續發送多個 HTTP 請求。這樣可以減少網路延遲，因為它消除了每個請求都要等到前一個完成後才能發送的等待時間。

要實現 HTTP 管道傳送，基本概念如下：

    同一個 TCP 連線：HTTP 管道傳送需要在同一個 TCP 連線上進行，這樣多個請求可以同時發送並依序接收回應。
    請求的順序處理：雖然請求是並行發送的，但伺服器仍然按順序處理這些請求，回應也會依據請求的順序返回給客戶端。
    需要 HTTP/1.1 支援：HTTP 管道傳送是 HTTP/1.1 規範中的一部分，並非所有伺服器和客戶端都支援它。
    效率提升有限：由於伺服器還是要依序回應請求，因此在實際應用中，HTTP 管道傳送的效能提升是有限的。HTTP/2 進一步改進了這一點，通過多路複用（Multiplexing）允許真正的並行傳送與回應。

```

#### Http Cache

```

Cache-control
可帶多個參數使用逗號隔開

1. max-age 
cache 有效時間 max-age=20 代表會儲存20秒
在network 傳輸上會顯示快取

2. public, private

定義：public 指令表示該資源可以被任何緩存系統存儲，包括瀏覽器、CDN、代理伺服器等。
適用場景：適合那些可以被多個用戶共享的資源，例如：CSS 文件、JavaScript 文件、圖片、公共 API 響應等，這些資源通常對所有用戶都相同。

定義：private 指令表示資源只能被單個用戶的緩存存儲，通常是瀏覽器緩存，不能被共享緩存（如代理伺服器、CDN 等）存儲。
適用場景：適合那些為特定用戶量身定制的資源，或包含個人數據的資源，例如：用戶個人資料頁面、購物車信息、登錄後的動態數據等。

3. no-store - 任何資料都不進行任何 cache
4. no-cache - 資料能被 cache 但每次使用前都必須向 server 進行驗證

etag 驗證

是基於資源內容的唯一標識符，更加精確，可以捕捉到所有資源變化，即使是極小的變化。
流程:
在 server 回傳後帶入 etag
client 端再重新打api時 瀏覽器會自動帶入 if-none-match
server 端實作驗證機制 回傳 304 或 200

Last-Modified 驗證
server 回傳後自動帶入 Last-Modified
client 端再重新打api時 瀏覽器會自動帶入 If-Modified-Since
server 端實作驗證機制 回傳 304 或 200

```

#### Http cookie

```

使用 set-cookie 會使下次的請求 get post 都自動帶入這個 cookie
max-age 設定當下多少時間後會失效 0 為刪除 cookie 單位(秒)
Expires 設定固定時間消失
httpOnly 代表不會被 document.cookie 存取到
Secure 只通過被 https 加密後的請求
```

#### HTTP Method

#### GET

```
從 server 取得資料
```

#### POST

```
在 server 建立一筆新資料
```

#### PUT

```
更新一筆已存在的資料
用於完整的替換一筆資源
```

#### PATCH

```
更新一筆已存在的資料
用於更新部分的資料
```

#### DELETE

```
刪除一筆資料
```

#### HEAD

```
與 get 類似
只獲得回應的 header 而不取得實際內容
```

#### OPTIONS

```
預先查詢 server path 中可以使用的 http 方法
```

#### TRACE

```
是 HTTP 中的一種診斷性請求方法，用於讓客戶端查看伺服器收到的原始請求。它會在伺服器端點回顯收到的請求，幫助客戶端了解請求是如何被伺服器接收的，並協助診斷或調試請求鏈中的問題
```

#### CONNECT

```
是 HTTP 的一種請求方法，主要用於建立到目標伺服器的隧道連接（通常為 TLS/SSL 加密連接），特別是在代理伺服器環境下，讓客戶端可以通過代理伺服器進行安全的 HTTPS 連接
```
