状态码使用 #
概述 #
HTTP 状态码是服务器响应请求时返回的三位数字代码,用于表示请求的处理结果。正确使用状态码是设计良好 API 的关键。
text
┌─────────────────────────────────────────────────────────────┐
│ HTTP 状态码分类 │
├─────────────────────────────────────────────────────────────┤
│ │
│ 1xx - 信息响应 │
│ 请求已接收,继续处理 │
│ │
│ 2xx - 成功响应 │
│ 请求已成功接收、理解、接受 │
│ │
│ 3xx - 重定向 │
│ 需要进一步操作以完成请求 │
│ │
│ 4xx - 客户端错误 │
│ 请求包含语法错误或无法完成 │
│ │
│ 5xx - 服务端错误 │
│ 服务器无法完成有效请求 │
│ │
└─────────────────────────────────────────────────────────────┘
2xx 成功状态码 #
常用成功状态码 #
text
┌─────────────────────────────────────────────────────────────┐
│ 2xx 成功状态码 │
├─────────────────────────────────────────────────────────────┤
│ │
│ 200 OK │
│ ───────────────────────────────────────────── │
│ 含义:请求成功 │
│ 场景:GET、PUT、PATCH 成功 │
│ 示例: │
│ GET /users/123 → 200 OK + 用户数据 │
│ PUT /users/123 → 200 OK + 更新后的用户数据 │
│ │
│ 201 Created │
│ ───────────────────────────────────────────── │
│ 含义:资源创建成功 │
│ 场景:POST 创建资源成功 │
│ 示例: │
│ POST /users → 201 Created + Location 头 + 新用户数据 │
│ │
│ 202 Accepted │
│ ───────────────────────────────────────────── │
│ 含义:请求已接受,正在处理 │
│ 场景:异步操作 │
│ 示例: │
│ POST /import → 202 Accepted + 任务 ID │
│ │
│ 204 No Content │
│ ───────────────────────────────────────────── │
│ 含义:请求成功,无返回内容 │
│ 场景:DELETE、PUT 成功(不需要返回数据) │
│ 示例: │
│ DELETE /users/123 → 204 No Content │
│ PUT /users/123 → 204 No Content │
│ │
│ 206 Partial Content │
│ ───────────────────────────────────────────── │
│ 含义:部分内容返回 │
│ 场景:范围请求(大文件下载) │
│ 示例: │
│ GET /files/large.zip → 206 Partial Content │
│ │
└─────────────────────────────────────────────────────────────┘
成功状态码选择指南 #
text
┌─────────────────────────────────────────────────────────────┐
│ 成功状态码选择 │
├─────────────────────────────────────────────────────────────┤
│ │
│ 操作类型 推荐状态码 说明 │
│ ───────────────────────────────────────────────────────── │
│ GET 资源列表 200 OK 返回资源列表 │
│ GET 单个资源 200 OK 返回资源数据 │
│ POST 创建资源 201 Created 返回新资源 │
│ PUT 完整更新 200/204 有数据返回 200 │
│ PATCH 部分更新 200/204 有数据返回 200 │
│ DELETE 删除资源 204/200 无数据返回 204 │
│ 异步操作 202 Accepted 返回任务信息 │
│ │
└─────────────────────────────────────────────────────────────┘
4xx 客户端错误 #
常用客户端错误状态码 #
text
┌─────────────────────────────────────────────────────────────┐
│ 4xx 客户端错误 │
├─────────────────────────────────────────────────────────────┤
│ │
│ 400 Bad Request │
│ ───────────────────────────────────────────── │
│ 含义:请求格式错误或参数无效 │
│ 场景:参数验证失败、格式错误 │
│ 示例: │
│ POST /users { "email": "invalid-email" } │
│ → 400 Bad Request │
│ │
│ 401 Unauthorized │
│ ───────────────────────────────────────────── │
│ 含义:未认证,需要登录 │
│ 场景:未提供认证信息或认证失败 │
│ 示例: │
│ GET /users/123 (无 Token) │
│ → 401 Unauthorized │
│ │
│ 403 Forbidden │
│ ───────────────────────────────────────────── │
│ 含义:已认证但无权限 │
│ 场景:权限不足 │
│ 示例: │
│ DELETE /users/123 (普通用户尝试删除管理员) │
│ → 403 Forbidden │
│ │
│ 404 Not Found │
│ ───────────────────────────────────────────── │
│ 含义:资源不存在 │
│ 场景:请求的资源不存在 │
│ 示例: │
│ GET /users/999999 │
│ → 404 Not Found │
│ │
│ 405 Method Not Allowed │
│ ───────────────────────────────────────────── │
│ 含义:不支持该 HTTP 方法 │
│ 场景:使用了不支持的方法 │
│ 示例: │
│ PATCH /users (集合不支持 PATCH) │
│ → 405 Method Not Allowed │
│ │
│ 406 Not Acceptable │
│ ───────────────────────────────────────────── │
│ 含义:无法生成客户端期望的内容类型 │
│ 场景:Accept 头指定不支持的格式 │
│ 示例: │
│ Accept: application/xml (只支持 JSON) │
│ → 406 Not Acceptable │
│ │
│ 409 Conflict │
│ ───────────────────────────────────────────── │
│ 含义:请求冲突 │
│ 场景:资源已存在、版本冲突 │
│ 示例: │
│ POST /users { "email": "exists@example.com" } │
│ → 409 Conflict │
│ │
│ 410 Gone │
│ ───────────────────────────────────────────── │
│ 含义:资源已永久删除 │
│ 场景:资源曾经存在但已删除 │
│ 示例: │
│ GET /users/deleted-user │
│ → 410 Gone │
│ │
│ 415 Unsupported Media Type │
│ ───────────────────────────────────────────── │
│ 含义:不支持的内容类型 │
│ 场景:Content-Type 不支持 │
│ 示例: │
│ Content-Type: text/plain │
│ → 415 Unsupported Media Type │
│ │
│ 422 Unprocessable Entity │
│ ───────────────────────────────────────────── │
│ 含义:语义错误,无法处理 │
│ 场景:格式正确但语义错误 │
│ 示例: │
│ POST /orders { "items": [] } // 空订单 │
│ → 422 Unprocessable Entity │
│ │
│ 429 Too Many Requests │
│ ───────────────────────────────────────────── │
│ 含义:请求过于频繁 │
│ 场景:触发速率限制 │
│ 示例: │
│ 超过速率限制 │
│ → 429 Too Many Requests │
│ │
└─────────────────────────────────────────────────────────────┘
401 vs 403 区别 #
text
┌─────────────────────────────────────────────────────────────┐
│ 401 vs 403 区别 │
├─────────────────────────────────────────────────────────────┤
│ │
│ 401 Unauthorized │
│ ───────────────────────────────────────────── │
│ 问题:你是谁? │
│ 含义:未认证,需要提供身份信息 │
│ 场景: │
│ - 未提供 Token │
│ - Token 过期 │
│ - Token 无效 │
│ │
│ 示例: │
│ GET /users/123 │
│ Authorization: Bearer invalid-token │
│ → 401 Unauthorized │
│ │
│ ───────────────────────────────────────────── │
│ │
│ 403 Forbidden │
│ ───────────────────────────────────────────── │
│ 问题:你能做这个吗? │
│ 含义:已认证但无权限 │
│ 场景: │
│ - 权限不足 │
│ - 角色不匹配 │
│ - 资源访问受限 │
│ │
│ 示例: │
│ GET /admin/users │
│ Authorization: Bearer user-token │
│ → 403 Forbidden │
│ │
└─────────────────────────────────────────────────────────────┘
400 vs 422 区别 #
text
┌─────────────────────────────────────────────────────────────┐
│ 400 vs 422 区别 │
├─────────────────────────────────────────────────────────────┤
│ │
│ 400 Bad Request │
│ ───────────────────────────────────────────── │
│ 问题:请求格式正确吗? │
│ 含义:请求格式错误或语法问题 │
│ 场景: │
│ - JSON 格式错误 │
│ - 缺少必填字段 │
│ - 字段类型错误 │
│ │
│ 示例: │
│ POST /users │
│ { "name": 123 } // name 应该是字符串 │
│ → 400 Bad Request │
│ │
│ ───────────────────────────────────────────── │
│ │
│ 422 Unprocessable Entity │
│ ───────────────────────────────────────────── │
│ 问题:数据语义正确吗? │
│ 含义:格式正确但语义错误 │
│ 场景: │
│ - 业务规则验证失败 │
│ - 数据逻辑错误 │
│ - 关联资源不存在 │
│ │
│ 示例: │
│ POST /orders │
│ { "productId": 999 } // 商品不存在 │
│ → 422 Unprocessable Entity │
│ │
└─────────────────────────────────────────────────────────────┘
5xx 服务端错误 #
常用服务端错误状态码 #
text
┌─────────────────────────────────────────────────────────────┐
│ 5xx 服务端错误 │
├─────────────────────────────────────────────────────────────┤
│ │
│ 500 Internal Server Error │
│ ───────────────────────────────────────────── │
│ 含义:服务器内部错误 │
│ 场景:未捕获的异常、代码错误 │
│ 示例: │
│ 数据库连接失败 │
│ → 500 Internal Server Error │
│ │
│ 502 Bad Gateway │
│ ───────────────────────────────────────────── │
│ 含义:网关错误 │
│ 场景:上游服务器返回无效响应 │
│ 示例: │
│ 代理服务器无法连接后端 │
│ → 502 Bad Gateway │
│ │
│ 503 Service Unavailable │
│ ───────────────────────────────────────────── │
│ 含义:服务不可用 │
│ 场景:服务器维护、过载 │
│ 示例: │
│ 服务器维护中 │
│ → 503 Service Unavailable │
│ │
│ 504 Gateway Timeout │
│ ───────────────────────────────────────────── │
│ 含义:网关超时 │
│ 场景:上游服务器响应超时 │
│ 示例: │
│ 后端服务响应超时 │
│ → 504 Gateway Timeout │
│ │
└─────────────────────────────────────────────────────────────┘
3xx 重定向状态码 #
常用重定向状态码 #
text
┌─────────────────────────────────────────────────────────────┐
│ 3xx 重定向状态码 │
├─────────────────────────────────────────────────────────────┤
│ │
│ 301 Moved Permanently │
│ ───────────────────────────────────────────── │
│ 含义:资源永久移动 │
│ 场景:URL 变更 │
│ 示例: │
│ GET /api/users → 301 → /v2/users │
│ │
│ 302 Found │
│ ───────────────────────────────────────────── │
│ 含义:资源临时移动 │
│ 场景:临时重定向 │
│ 示例: │
│ GET /old-url → 302 → /new-url │
│ │
│ 304 Not Modified │
│ ───────────────────────────────────────────── │
│ 含义:资源未修改 │
│ 场景:缓存验证成功 │
│ 示例: │
│ GET /users/123 │
│ If-None-Match: "old-etag" │
│ → 304 Not Modified │
│ │
│ 307 Temporary Redirect │
│ ───────────────────────────────────────────── │
│ 含义:临时重定向,保持请求方法 │
│ 场景:临时重定向 │
│ │
│ 308 Permanent Redirect │
│ ───────────────────────────────────────────── │
│ 含义:永久重定向,保持请求方法 │
│ 场景:永久 URL 变更 │
│ │
└─────────────────────────────────────────────────────────────┘
状态码速查表 #
text
┌─────────────────────────────────────────────────────────────┐
│ 状态码速查表 │
├─────────────────────────────────────────────────────────────┤
│ │
│ 场景 状态码 │
│ ───────────────────────────────────────────────────────── │
│ 请求成功 200 OK │
│ 创建资源成功 201 Created │
│ 删除成功 204 No Content │
│ 更新成功 200 OK / 204 No Content │
│ 异步任务已接受 202 Accepted │
│ │
│ 参数错误 400 Bad Request │
│ 未认证 401 Unauthorized │
│ 无权限 403 Forbidden │
│ 资源不存在 404 Not Found │
│ 方法不支持 405 Method Not Allowed │
│ 资源冲突 409 Conflict │
│ 验证失败 422 Unprocessable Entity │
│ 请求过于频繁 429 Too Many Requests │
│ │
│ 服务器错误 500 Internal Server Error │
│ 服务不可用 503 Service Unavailable │
│ 网关超时 504 Gateway Timeout │
│ │
│ 资源未修改(缓存) 304 Not Modified │
│ 资源永久移动 301 Moved Permanently │
│ │
└─────────────────────────────────────────────────────────────┘
状态码使用检查清单 #
text
□ 成功响应
□ GET 成功返回 200 OK
□ POST 创建成功返回 201 Created
□ DELETE 成功返回 204 No Content
□ PUT/PATCH 成功返回 200 或 204
□ 客户端错误
□ 参数错误返回 400 Bad Request
□ 未认证返回 401 Unauthorized
□ 无权限返回 403 Forbidden
□ 资源不存在返回 404 Not Found
□ 冲突返回 409 Conflict
□ 验证失败返回 422 Unprocessable Entity
□ 速率限制返回 429 Too Many Requests
□ 服务端错误
□ 服务器错误返回 500 Internal Server Error
□ 服务不可用返回 503 Service Unavailable
□ 重定向
□ 缓存命中返回 304 Not Modified
□ URL 变更返回 301/308
下一步 #
现在你已经了解了状态码的正确使用,接下来学习 API 版本管理,深入了解如何管理 API 版本!
最后更新:2026-03-29