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 內容

一次完整訪問的端到端流程(DNS → TCP → HTTP → 伺服器處理 → 渲染)已在「網路基礎與分層模型」一章說明,本章聚焦 HTTP 協定本身。

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 長度限制無限制
快取可快取不可快取
語義讀取資料提交資料

狀態碼#

狀態碼分類#

分類含義
1xx資訊性,處理中
2xx成功
3xx重新導向
4xx用戶端錯誤
5xx伺服器錯誤

常見狀態碼#

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 預設長連接,但有隊頭阻塞問題
資料傳輸支援壓縮、分塊、範圍請求