文章目錄
- 寫在前面
- 問題描述
- 核心結論與建議
- 簡要描述
- 詳細闡述
- 1xx - 信息性響應 (Informational)
- 2xx - 成功 (Successful)
- 3xx - 重定向 (Redirection)
- 4xx - 客戶端錯誤 (Client Error)
- 5xx - 服務器錯誤 (Server Error)
- HTTP 狀態碼速查表
- 參考以及更多更詳細的狀態碼查詢
寫在前面
你是否見過這樣的 API:無論操作成功、參數錯誤還是找不到資源,它都固執地返回 200 OK,然后把真正的狀態信息藏在響應體的某個角落,比如 {“code”: 5001, “message”: “參數不能為空”}?
這種設計看似“統一”,實則嚴重違反了 RESTful 的核心原則,極大地增加了客戶端的對接成本和出錯概率。HTTP 狀態碼并非擺設,它們是服務器與客戶端之間溝通的標準語言,是 API 自我描述能力的重要組成部分。
本文旨在建立一套清晰、統一的 HTTP 狀態碼使用規范,幫助你和你的團隊構建出更健壯、更易于理解和使用的 API。
問題描述
在RESTful API設計中,僅僅返回200(成功)或500(服務器錯誤)是遠遠不夠的。不規范的狀態碼會嚴重影響API的可用性和開發者的對接效率。
本次調研旨在建立一套清晰、統一的HTTP狀態碼使用規范,核心目標是:當API調用出現各類情況(如參數不合法、無權限、資源不存在等)時,能夠返回最恰當的狀態碼和最清晰的錯誤信息,提升API的健壯性和開發者體驗。
核心結論與建議
參數不合法應該返回什么?
首選答案:400 Bad Request
這是最通用、最符合HTTP規范的選擇。當服務器因客戶端發送的請求本身有錯誤(例如,數據格式錯誤、缺少必需參數、參數值超出業務范圍等)而無法處理時,應返回此狀態碼。
更精確的選擇:422 Unprocessable Entity
在特定場景下,422 是比 400 更精確的補充。它們的區別在于:
- 400 Bad Request: 請求語法有誤。服務器無法理解請求,如JSON格式損壞。
- 422 Unprocessable Entity: 請求語義有誤。服務器能理解請求,但因業務規則限制無法處理,如必填字段為空、年齡為負數。
對于絕大多數團隊,統一使用 400 Bad Request 來表示所有類型的參數驗證失敗,是更簡單且完全可接受的最佳實踐。
簡要描述
HTTP狀態碼是RESTful API設計中非常核心的一部分,是三位整數代碼,它們是服務器與客戶端之間溝通的“標準語言”。
HTTP 狀態碼是可擴展的。HTTP 客戶端無需理解所有已注冊狀態碼的含義,盡管理解這些含義顯然是更好的。但是,客戶端必須理解任何狀態碼的類別(由第一位數字指示),并將無法識別的狀態碼視為該類別的 x00 狀態碼,例如,如果客戶端收到無法識別的狀態碼 471,則客戶端可以假定其請求存在問題,并將該響應視為收到了 400(錯誤請求)狀態碼。響應消息通常包含一個解釋狀態的表示。
這些狀態碼被分為五大類,由第一位數字標識(第一位數字定義了響應的類別,最后兩位數字不具有任何分類作用):
- 1xx (Informational): 信息性響應 - 表示請求已接收,繼續處理。
- 2xx (Successful): 成功 - 表示請求已被成功接收、理解、并接受。
- 3xx (Redirection): 重定向 - 表示需要客戶端采取進一步的操作才能完成請求。
- 4xx (Client Error): 客戶端錯誤 - 表示請求包含語法錯誤或無法完成請求。
- 5xx (Server Error): 服務器錯誤 - 表示服務器在處理一個看似有效的請求時發生錯誤。
詳細闡述
1xx - 信息性響應 (Informational)
這類狀態碼在日常API開發中非常少見,主要用于協議內部交互。
100 Continue (繼續):客戶端準備發送一個大的請求體(如POST一個大文件)時,可以先發送一個只包含頭信息的請求,并攜帶Expect: 100-continue頭。如果服務器愿意接收,就返回100,客戶端再繼續發送請求體。這可以避免因服務器拒絕而浪費帶寬。
101 Switching Protocols (切換協議):客戶端請求升級協議(例如,從HTTP/1.1升級到WebSocket),服務器同意切換時返回此碼。
102 Processing (處理中):(WebDAV擴展) 一個請求可能包含多個子操作,需要較長時間完成。服務器返回102以防止客戶端超時,表示請求已收到且正在處理中。
2xx - 成功 (Successful)
這是API設計中最常用的一類,表示操作成功。
200 OK (成功):最通用的成功狀態碼。表示請求已成功,響應體中通常包含請求的資源。適用于GET(獲取數據)、PUT(更新整個資源)、PATCH(部分更新資源)以及不創建新資源的POST操作的成功響應。
201 Created (已創建):專門用于創建新資源。當客戶端通過POST請求成功創建了一個新資源時返回。最佳實踐是在響應頭的Location字段中包含新資源的URL。
202 Accepted (已接受): 用于異步任務。服務器已接收請求,但尚未處理完成。這并不保證最終任務會成功。適用于需要長時間處理的操作,如視頻轉碼、生成報表等。客戶端可以后續通過輪詢或其他機制查詢任務狀態。
204 No Content (無內容): 服務器成功處理了請求,但響應體中沒有任何內容返回。常用于DELETE請求成功后,或PUT更新操作成功但無需返回資源內容時。
206 Partial Content (部分內容):(不常用) 用于范圍請求(Range Requests),表示服務器成功返回了資源的一部分,例如視頻流或大文件分塊下載。
3xx - 重定向 (Redirection)
表示客戶端需要執行后續操作才能完成請求。
301 Moved Permanently (永久移動): 請求的資源已被永久移動到新的URL。搜索引擎會更新其索引。API客戶端應該將本地書簽也更新到新的URL。
302 Found (找到):請求的資源臨時位于不同的URL。客戶端應該使用這個臨時的URL來發送本次請求,但下次還應該使用原始URL。常用于傳統的Web頁面重定向,API中較少使用。
303 See Other (查看其他):(與302類似但更明確) 建議客戶端使用GET方法去請求另一個URL來獲取結果。主要用于POST請求后,防止用戶刷新頁面導致重復提交。
304 Not Modified (未修改):用于緩存控制。當客戶端發送一個帶條件的GET請求(如使用If-None-Match或If-Modified-Since頭),如果服務器發現資源自上次請求以來未發生變化,則返回此碼,并且不包含響應體,從而節省帶寬。
307 Temporary Redirect (臨時重定向):(與302類似但更嚴格) 要求客戶端在重定向到新URL時,保持原始請求方法不變。例如,如果原始請求是POST,那么對新URL的請求也必須是POST。
4xx - 客戶端錯誤 (Client Error)
API設計中最需要關注和細化的一類,表示錯誤源于客戶端。
400 Bad Request (錯誤請求):通用的客戶端錯誤。表示服務器因客戶端發送的請求語法錯誤而無法解析。最常見的用途是參數驗證失敗,如缺少必需字段、字段格式錯誤、數值超出范圍等。
401 Unauthorized (未授權):用戶未認證。客戶端必須先進行身份驗證(例如,提供有效的Token或API Key)才能訪問該資源。它表達的是“你是誰?”的問題。
403 Forbidden (禁止訪問):用戶沒權限。服務器已經知道客戶端的身份,但該身份沒有權限訪問此資源。它表達的是“我知道你是誰,但你不能做這個操作”的問題。
404 Not Found (未找到):請求的資源不存在。例如,GET /api/users/9999,但ID為9999的用戶不存在。
405 Method Not Allowed (方法不允許):客戶端使用了當前資源不支持的HTTP方法。例如,對一個只讀資源使用POST。服務器應在Allow頭中返回支持的方法列表。
406 Not Acceptable (不可接受):(不常用) 服務器無法根據客戶端請求頭中的Accept字段(如Accept: application/xml)生成任何可接受的表示形式。
409 Conflict (沖突):請求的操作與服務器資源的當前狀態發生沖突。最常見的例子是嘗試創建一個已經存在的唯一資源(如注冊一個已被占用的用戶名或郵箱)。
410 Gone (已移除):(比404更明確) 請求的資源曾經存在,但現在已被永久刪除,并且不會再可用。
413 Payload Too Large (負載過大):客戶端發送的請求體大小超過了服務器的限制。
415 Unsupported Media Type (不支持的媒體類型):客戶端發送的請求體使用了服務器不支持的媒體類型(由Content-Type頭指定)。例如,API只接受application/json,但客戶端發送了application/xml。
422 Unprocessable Entity (無法處理的實體):(WebDAV擴展,但被廣泛用于API) 請求的語法正確,但語義錯誤,導致服務器無法處理。這是400的一個更具體的版本,專門用于業務邏輯層面的驗證失敗。
429 Too Many Requests (請求過多):API限流。客戶端在單位時間內發送的請求數量超過了服務器設定的速率限制。
5xx - 服務器錯誤 (Server Error)
表示錯誤源于服務器端,客戶端通常無法解決。
500 Internal Server Error (服務器內部錯誤):通用的服務器端錯誤。表示服務器遇到了一個未知的、無法處理的意外情況,例如代碼中出現未捕獲的異常、數據庫連接問題等。絕不能在響應中暴露敏感的錯誤細節。
501 Not Implemented (未實現):服務器不支持當前請求所需要的功能。例如,客戶端使用了服務器無法識別的請求方法。
502 Bad Gateway (錯誤網關):作為網關或代理的服務器,從其上游服務器(如應用服務器)處收到了無效的響應。
503 Service Unavailable (服務不可用):服務器當前無法處理請求,通常是臨時性的。原因可能是服務器過載、正在進行維護或部署。服務器可以在Retry-After頭中告知客戶端何時可以重試。
504 Gateway Timeout (網關超時):作為網關或代理的服務器,未能及時從其上游服務器獲得響應。
HTTP 狀態碼速查表
類別 | 狀態碼 | 名稱 | 核心適用場景 |
---|---|---|---|
信息性響應(1xx) | 100 Continue | 繼續 | 交互是否繼續發送 |
101 Switching Protocols | 切換協議 | 切換協議 | |
102 Processing | 處理中 | 防止客戶端超時。請求包含多個子操作,需要較長時間 | |
成功 (2xx) | 200 OK | 成功 | 通用成功。GET, PUT, PATCH, POST(不創建新資源), DELETE 成功 |
201 Created | 已創建 | 資源創建成功 (專用于POST) | |
202 Accepted | 已接受 | 異步任務,請求已接收,正在后臺處理 | |
204 No Content | 無內容 | 成功處理,但無返回內容 (如DELETE成功) | |
206 Partial Content | 部分內容 | 服務器成功返回了資源的一部分,例如視頻流或大文件分塊下載 | |
重定向 (3xx) | 301 Moved Permanently | 永久移動 | 資源 URL 永久變更 |
302 Found | 找到 | 請求的資源臨時位于不同的URL | |
303 See Other | 查看其他 | 建議客戶端使用GET方法去請求另一個URL來獲取結果 | |
304 Not Modified | 未修改 | 緩存命中,資源無變化 | |
307 Temporary Redirect | 臨時重定向 | 要求客戶端在重定向到新URL時,保持原始請求方法不變 | |
客戶端錯誤 (4xx) | 400 Bad Request | 錯誤請求 | 參數驗證失敗 (通用客戶端錯誤) |
401 Unauthorized | 未授權 | 需要認證 (未登錄或Token無效) | |
403 Forbidden | 禁止訪問 | 權限不足 (已登錄但無權操作) | |
404 Not Found | 未找到 | 請求的資源不存在 | |
405 Method Not Allowed | 方法不允許 | HTTP 請求方法錯誤 (如對只讀資源用POST) | |
406 Not Acceptable | 不可接受 | 服務器無法根據客戶端請求頭中的Accept字段生成任何可接受的表示形式 | |
409 Conflict | 沖突 | 資源狀態沖突 (如創建已存在的用戶) | |
410 Gone | 已移除 | 請求的資源曾經存在,但現在已被永久刪除,并且不會再可用 | |
413 Payload Too Large | 負載過大 | 客戶端發送的請求體大小超過了服務器的限制 | |
415 Unsupported Media Type | 不支持的媒體類型 | 客戶端發送的請求體使用了服務器不支持的媒體類型(由Content-Type頭指定) | |
422 Unprocessable Entity | 無法處理的實體 | 請求的語法正確,但業務語義錯誤 (400的更具體版本),專用于業務邏輯層面的驗證失敗 | |
429 Too Many Requests | 請求過多 | API 限流 | |
服務器錯誤 (5xx) | 500 Internal Server Error | 服務器內部錯誤 | 通用服務器端代碼/環境異常 |
501 Not Implemented | 未實現 | 服務器不支持當前請求所需要的功能 | |
502 Bad Gateway | 錯誤網關 | 網關/代理從上游收到無效響應 | |
503 Service Unavailable | 服務不可用 | 服務器臨時過載、維護或部署 | |
504 Gateway Timeout | 網關超時 | 網關/代理從上游請求超時 |
參考以及更多更詳細的狀態碼查詢
權威標準-IETF RFCs
RFC 7231: Hypertext Transfer Protocol (HTTP/1.1): Semantics and Content: 6. Response Status Codes
RFC 6585: Additional HTTP Status Codes
RFC 4918: HTTP Extensions for Web Distributed Authoring and Versioning (WebDAV)
開發者圣經-MDN Web Docs
HTTP 響應狀態碼 - HTTP | MDN
快速查詢
HTTP Status Codes Glossary - WebFX
趣味記憶
HTTP Cats