HTTP 協定#

HTTP(HyperText Transfer Protocol)是應用層協定,是 Web 通信的基礎。本章涵蓋 HTTP 報文結構、請求方法、狀態碼、頭字段和連接管理。

HTTP 基礎#

請求-回應模型#

HTTP 採用經典的請求-回應模型:

sequenceDiagram
    participant C as 客戶端(瀏覽器)
    participant S as 伺服器

    C->>S: HTTP 請求<br/>GET /index.html
    S->>C: HTTP 回應<br/>200 OK + HTML 內容

一次完整的訪問過程#

  1. DNS 解析:域名轉換為 IP 地址
  2. TCP 三次握手:建立連接
  3. 發送 HTTP 請求:構建並發送請求報文
  4. 伺服器處理:解析請求,處理業務邏輯
  5. 返回 HTTP 回應:構建並發送回應報文
  6. 瀏覽器渲染:解析 HTML/CSS/JS,顯示頁面

HTTP 報文結構#

報文組成#

HTTP 報文由 Header + Body 組成:

組成部分說明是否必須
起始行(請求行/狀態行)請求方法或狀態碼必須
頭字段Key: Value 格式的元資料必須
空行(CRLF)分隔 Header 和 Body必須
消息正文(Body)實際傳輸的資料可選

HTTP 報文必須有 Header,但可以沒有 Body。Header 和 Body 之間必須有空行(CRLF)。

請求報文範例#

GET /api/users HTTP/1.1
Host: www.example.com
User-Agent: Mozilla/5.0
Accept: application/json
Accept-Language: zh-TW,zh;q=0.9,en;q=0.8
Connection: keep-alive

回應報文範例#

HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
Content-Length: 128
Date: Mon, 26 Jan 2026 08:00:00 GMT
Connection: keep-alive

{"users": [{"id": 1, "name": "Alice"}]}

請求方法#

常用方法#

方法語義安全性冪等性Body
GET獲取資源安全冪等
HEAD獲取元資訊安全冪等
POST提交資料/創建資源不安全非冪等
PUT替換資源不安全冪等
DELETE刪除資源不安全冪等可選
PATCH部分更新資源不安全非冪等
OPTIONS查詢支援的方法安全冪等
安全與冪等的含義
  • 安全(Safe):不會修改伺服器上的資源
  • 冪等(Idempotent):執行多次和執行一次效果相同

理解冪等性可以類比 SQL:

  • POSTINSERT:多次執行會創建多條記錄
  • PUTUPDATE:多次執行結果相同

GET vs POST#

特性GETPOST
資料位置URL 查詢參數Body
資料長度受 URL 長度限制無限制
快取可快取不可快取
歷史記錄會保存不會保存
書籤可收藏不可收藏
語義讀取資料提交資料

狀態碼#

狀態碼分類#

分類範圍含義
1xx100-199資訊性,處理中
2xx200-299成功
3xx300-399重定向
4xx400-499客戶端錯誤
5xx500-599伺服器錯誤

常見狀態碼#

2xx 成功

狀態碼名稱說明
200OK請求成功
201Created資源創建成功(POST 後)
204No Content成功但無返回內容
206Partial部分內容(範圍請求)

3xx 重定向

狀態碼名稱說明
301Moved Permanently永久重定向
302Found臨時重定向
304Not Modified未修改(快取有效)

4xx 客戶端錯誤

狀態碼名稱說明
400Bad Request請求格式錯誤
401Unauthorized未認證
403Forbidden禁止訪問
404Not Found資源不存在
405Method Not Allowed方法不允許
429Too Many Requests請求過多

5xx 伺服器錯誤

狀態碼名稱說明
500Internal Error伺服器內部錯誤
502Bad Gateway網關錯誤
503Service Unavailable服務不可用
504Gateway Timeout網關超時

301 是永久重定向(如 HTTP 跳轉 HTTPS),瀏覽器會快取;302 是臨時重定向,每次都會請求原地址。

常用頭字段#

通用頭字段#

字段說明範例
Date報文創建時間Date: Mon, 26 Jan 2026 08:00:00 GMT
Connection連接管理Connection: keep-alive
Cache-Control快取控制Cache-Control: max-age=3600

請求頭字段#

字段說明範例
Host目標主機(必須)Host: www.example.com
User-Agent客戶端資訊User-Agent: Mozilla/5.0...
Accept可接受的 MIME 類型Accept: text/html,application/json
Accept-Encoding可接受的壓縮格式Accept-Encoding: gzip, deflate, br
Accept-Language可接受的語言Accept-Language: zh-TW,en
Cookie攜帶 CookieCookie: session=abc123
Authorization認證資訊Authorization: Bearer token...

回應頭字段#

字段說明範例
Content-Type內容類型Content-Type: text/html; charset=utf-8
Content-Length內容長度Content-Length: 1024
Content-Encoding內容編碼Content-Encoding: gzip
Set-Cookie設置 CookieSet-Cookie: session=abc; HttpOnly
Location重定向地址Location: https://new.example.com

內容協商#

客戶端和伺服器協商返回最合適的內容:

# 請求
Accept: text/html,application/json;q=0.9,*/*;q=0.8
Accept-Encoding: gzip, deflate, br
Accept-Language: zh-TW,zh;q=0.9,en;q=0.8

# 回應
Content-Type: text/html; charset=utf-8
Content-Encoding: gzip
Content-Language: zh-TW

q 值表示優先級權重,範圍 0-1,默認為 1。q=0 表示不接受。

連接管理#

短連接 vs 長連接#

短連接(HTTP/1.0 默認)

sequenceDiagram
    participant C as 客戶端
    participant S as 伺服器

    C->>S: 建立連接
    C->>S: 請求1
    S->>C: 回應1
    C->>S: 關閉連接

    C->>S: 建立連接
    C->>S: 請求2
    S->>C: 回應2
    C->>S: 關閉連接

長連接(HTTP/1.1 默認)

sequenceDiagram
    participant C as 客戶端
    participant S as 伺服器

    C->>S: 建立連接
    C->>S: 請求1
    S->>C: 回應1
    C->>S: 請求2
    S->>C: 回應2
    C->>S: 請求3
    S->>C: 回應3
    Note over C,S: 連接保持,可繼續請求
特性短連接長連接
連接開銷每次請求都要三次握手一次握手,多次請求
效率
伺服器資源每次釋放需要維護連接狀態
適用場景低頻請求高頻請求

連接控制#

# 請求使用長連接(HTTP/1.1 默認)
Connection: keep-alive

# 請求關閉連接
Connection: close

伺服器可以設置長連接策略:

# Nginx 組態
keepalive_timeout 60;    # 空閒超時 60 秒
keepalive_requests 100;  # 最多處理 100 個請求

隊頭阻塞問題#

HTTP/1.1 的長連接是串行的,前面的請求阻塞會影響後面的請求:

請求 A(耗時 5s)→ 請求 B(等待)→ 請求 C(等待)
                    阻塞!           阻塞!

隊頭阻塞是 HTTP/1.1 的固有缺陷,無法完全解決。HTTP/2 通過多路復用解決了這個問題。

緩解策略#

策略說明
並發連接同一域名開多個連接(瀏覽器限制 6-8 個)
域名分片多個域名指向同一伺服器,繞過連接數限制
資源合併CSS/JS 合併,減少請求數
雪碧圖多個小圖合併為一張大圖

資料傳輸#

壓縮傳輸#

# 請求告知支援的壓縮格式
Accept-Encoding: gzip, deflate, br

# 回應告知使用的壓縮格式
Content-Encoding: gzip

常用壓縮算法:

算法特點
gzip最常用,兼容性好
deflate較老的算法
br (Brotli)Google 開發,壓縮率更高

分塊傳輸#

用於不知道內容總長度的情況:

HTTP/1.1 200 OK
Transfer-Encoding: chunked

7\r\n
Mozilla\r\n
9\r\n
Developer\r\n
0\r\n
\r\n

Transfer-Encoding: chunkedContent-Length 互斥,不能同時使用。

範圍請求#

支援斷點續傳和多線程下載:

# 請求部分內容
GET /video.mp4 HTTP/1.1
Range: bytes=0-1023

# 回應
HTTP/1.1 206 Partial Content
Content-Range: bytes 0-1023/10240
Content-Length: 1024

常用工具#

# curl 發送請求
curl -v https://example.com
curl -X POST -d '{"name":"test"}' -H "Content-Type: application/json" https://api.example.com

# 查看回應頭
curl -I https://example.com

# httpie(更友好的 HTTP 客戶端)
http GET https://example.com
http POST https://api.example.com name=test

本章小結#

概念關鍵點
報文結構Header + 空行 + Body,Header 必須,Body 可選
請求方法GET 讀取,POST 提交,PUT 替換,DELETE 刪除
狀態碼2xx 成功,3xx 重定向,4xx 客戶端錯誤,5xx 伺服器錯誤
頭字段Host 必須,Accept/Content-Type 協商內容類型
連接管理HTTP/1.1 默認長連接,但有隊頭阻塞問題
資料傳輸支援壓縮、分塊、範圍請求