狀態碼寶典(上):1xx-3xx 資訊、成功與重導向
HTTP 狀態碼是伺服器對請求的「回答」,它用三位數字告訴客戶端:請求成功了嗎?失敗了是誰的錯?需要做什麼額外處理?本篇將完整解析 1xx 到 3xx 的所有常見狀態碼。
一、 狀態碼總覽
1.1 分類規則
| 範圍 | 類別 | 含義 |
|---|---|---|
| 1xx | Informational | 資訊性回應,請求已接收,繼續處理 |
| 2xx | Success | 成功,請求已正確處理 |
| 3xx | Redirection | 重導向,需要進一步操作 |
| 4xx | Client Error | 客戶端錯誤(下一篇) |
| 5xx | Server Error | 伺服器錯誤(下一篇) |
1.2 狀態碼結構
HTTP/1.1 200 OK
^^^ ^^
| └─ 原因短語(Reason Phrase)
└───── 狀態碼(Status Code)NOTE
HTTP/2 和 HTTP/3 已移除原因短語,只保留狀態碼數字。
二、 1xx 資訊性回應
1xx 狀態碼表示「伺服器已收到請求,正在處理中」。這類回應較少見,但在特定場景很重要。
100 Continue
含義:伺服器已收到請求標頭,客戶端可以繼續發送 Body
使用場景:上傳大型檔案時,先確認伺服器願意接收
101 Switching Protocols
含義:伺服器同意切換協定
使用場景:WebSocket 握手
# 請求
GET /chat HTTP/1.1
Host: example.com
Upgrade: websocket
Connection: Upgrade
# 回應
HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade103 Early Hints
含義:在最終回應前,預先告知客戶端可以預載的資源
使用場景:優化頁面載入速度
HTTP/1.1 103 Early Hints
Link: </style.css>; rel=preload; as=style
Link: </script.js>; rel=preload; as=script
# 稍後...
HTTP/1.1 200 OK
Content-Type: text/html
...TIP
103 Early Hints 是 HTTP/2 和 HTTP/3 的優化利器,可讓瀏覽器在伺服器處理期間就開始預載資源。
三、 2xx 成功回應
2xx 狀態碼表示「請求已成功處理」。這是最常見的回應類別。
200 OK
含義:請求成功
使用場景:最常見的成功回應
# GET 請求
HTTP/1.1 200 OK
Content-Type: application/json
{"id": 1, "name": "John"}
# POST 請求(非創建資源的操作)
HTTP/1.1 200 OK
Content-Type: application/json
{"success": true, "message": "操作完成"}201 Created
含義:資源已成功創建
使用場景:POST 請求創建新資源
POST /api/users HTTP/1.1
Content-Type: application/json
{"name": "John", "email": "john@example.com"}
HTTP/1.1 201 Created
Location: /api/users/123
Content-Type: application/json
{"id": 123, "name": "John", "email": "john@example.com"}重點:
- 應包含
Location標頭指向新資源 - Body 中可包含創建的資源內容
202 Accepted
含義:請求已接受,但尚未處理完成
使用場景:異步處理、佇列任務
POST /api/reports/generate HTTP/1.1
HTTP/1.1 202 Accepted
Content-Type: application/json
Location: /api/jobs/456
{
"jobId": "456",
"status": "pending",
"checkStatusAt": "/api/jobs/456"
}204 No Content
含義:請求成功,但沒有內容可返回
使用場景:DELETE 成功、PUT 更新成功(無需返回資料)
DELETE /api/users/123 HTTP/1.1
HTTP/1.1 204 No Content注意:
- 204 不應有 Body
- 常用於「靜默成功」的操作
206 Partial Content
含義:返回資源的部分內容
使用場景:斷點續傳、視頻串流
# 請求
GET /video.mp4 HTTP/1.1
Range: bytes=0-1023
# 回應
HTTP/1.1 206 Partial Content
Content-Range: bytes 0-1023/1048576
Content-Length: 1024
(前 1024 bytes 的內容)Range 請求的工作原理:
四、 3xx 重導向
3xx 狀態碼表示「需要進一步操作才能完成請求」。
3.1 重導向分類
| 狀態碼 | 永久/臨時 | 方法改變 | 可快取 |
|---|---|---|---|
| 301 | 永久 | GET → GET | ✅ |
| 302 | 臨時 | 可能改變 | ❌ |
| 303 | 臨時 | 任何 → GET | ❌ |
| 307 | 臨時 | 不改變 | ❌ |
| 308 | 永久 | 不改變 | ✅ |
301 Moved Permanently
含義:資源已永久移動到新位置
使用場景:網站遷移、URL 規範化
GET /old-page HTTP/1.1
HTTP/1.1 301 Moved Permanently
Location: https://www.example.com/new-page特點:
- 瀏覽器會快取此重導向
- 搜尋引擎會更新索引到新 URL
- 原請求方法可能被改為 GET(歷史行為)
302 Found
含義:資源臨時位於其他位置
使用場景:臨時維護頁面
HTTP/1.1 302 Found
Location: /maintenance.htmlWARNING
302 的歷史行為不一致:有些瀏覽器會將 POST 改為 GET。如果需要保持方法,請使用 307。
303 See Other
含義:應使用 GET 請求另一個 URL
使用場景:POST-Redirect-GET 模式
304 Not Modified
含義:資源未修改,可使用快取版本
使用場景:快取驗證
# 請求
GET /style.css HTTP/1.1
If-None-Match: "abc123"
# 回應
HTTP/1.1 304 Not Modified
ETag: "abc123"特點:
- 沒有 Body,節省頻寬
- 搭配
If-None-Match或If-Modified-Since使用
307 Temporary Redirect
含義:臨時重導向,保持原請求方法
使用場景:需要保持 POST 的臨時重導向
POST /api/process HTTP/1.1
HTTP/1.1 307 Temporary Redirect
Location: /api/process-v2
# 客戶端會向 /api/process-v2 發送相同的 POST 請求308 Permanent Redirect
含義:永久重導向,保持原請求方法
使用場景:API 版本升級(保持 POST)
POST /api/v1/users HTTP/1.1
HTTP/1.1 308 Permanent Redirect
Location: /api/v2/users五、 重導向最佳實踐
5.1 選擇正確的狀態碼
5.2 避免重導向鏈
# ❌ 不好:多次重導向
/page → 301 → /page/ → 301 → https://www.example.com/page/
# ✅ 好:直接到最終目標
/page → 301 → https://www.example.com/page/5.3 常見重導向場景
| 場景 | 建議狀態碼 |
|---|---|
| HTTP → HTTPS | 301 |
| www → non-www | 301 |
| 舊 URL → 新 URL | 301 |
| 登入後跳轉 | 303 |
| 表單提交後 | 303 |
| A/B 測試 | 302 |
| 維護頁面 | 302 或 503 |
| API 版本升級 | 308 |
六、 實用速查表
1xx 系列
| 狀態碼 | 名稱 | 常見場景 |
|---|---|---|
| 100 | Continue | 大型上傳前確認 |
| 101 | Switching Protocols | WebSocket 握手 |
| 103 | Early Hints | 預載資源提示 |
2xx 系列
| 狀態碼 | 名稱 | 常見場景 |
|---|---|---|
| 200 | OK | 一般成功回應 |
| 201 | Created | 創建資源成功 |
| 202 | Accepted | 異步處理已接受 |
| 204 | No Content | 刪除成功、靜默更新 |
| 206 | Partial Content | 斷點續傳、Range 請求 |
3xx 系列
| 狀態碼 | 名稱 | 常見場景 |
|---|---|---|
| 301 | Moved Permanently | 永久 URL 變更 |
| 302 | Found | 臨時重導向 |
| 303 | See Other | POST 後跳轉 |
| 304 | Not Modified | 快取驗證 |
| 307 | Temporary Redirect | 保持方法的臨時跳轉 |
| 308 | Permanent Redirect | 保持方法的永久跳轉 |
總結
| 類別 | 含義 | 客戶端行為 |
|---|---|---|
| 1xx | 處理中 | 等待或繼續發送 |
| 2xx | 成功 | 處理回應內容 |
| 3xx | 重導向 | 跟隨 Location 標頭 |
> **記憶口訣**:
- 1xx = 「等一下」
- 2xx = 「沒問題」
- 3xx = 「去別處」
進階挑戰
- 使用 cURL 的
-I和-L參數,追蹤http://google.com的完整重導向鏈。 - 設計一個支援斷點續傳的檔案下載 API,寫出請求和回應的完整 Headers。
- 思考:為什麼 304 Not Modified 不應該有 Body?如果回傳 Body 會發生什麼?