HTTP 状态码参考

HTTP 状态码完整列表

1xx 1xx 信息

100
Continue
Server received request headers, client should proceed
101
Switching Protocols
Server is switching protocols as requested
102
Processing
Server is processing the request (WebDAV)
103
Early Hints
Used to return response headers before final response

2xx 2xx 成功

200
OK
Request succeeded
201
Created
Request succeeded, new resource created
202
Accepted
Request accepted for processing
203
Non-Authoritative Information
Metadata from third-party copy
204
No Content
No content to send, headers may be useful
205
Reset Content
Reset the document that sent this request
206
Partial Content
Partial resource due to Range header
207
Multi-Status
Multiple status codes (WebDAV)
208
Already Reported
DAV binding already reported (WebDAV)

3xx 3xx 重定向

300
Multiple Choices
Multiple options for the resource
301
Moved Permanently
Resource moved permanently to new URL
302
Found
Resource temporarily moved to different URL
303
See Other
Response found at another URI using GET
304
Not Modified
Resource not modified since last request
307
Temporary Redirect
Temporary redirect, keep HTTP method
308
Permanent Redirect
Permanent redirect, keep HTTP method

4xx 4xx 客户端错误

400
Bad Request
Server cannot process due to client error
401
Unauthorized
Authentication required
402
Payment Required
Reserved for future use
403
Forbidden
Server refuses to authorize
404
Not Found
Resource not found
405
Method Not Allowed
HTTP method not allowed
406
Not Acceptable
No content conforming to Accept headers
407
Proxy Authentication Required
Proxy authentication needed
408
Request Timeout
Server timed out waiting for request
409
Conflict
Request conflicts with server state
410
Gone
Resource permanently deleted
411
Length Required
Content-Length header required
412
Precondition Failed
Precondition in headers not met
413
Payload Too Large
Request entity too large
414
URI Too Long
URI too long for server
415
Unsupported Media Type
Media format not supported
416
Range Not Satisfiable
Range specified can't be fulfilled
417
Expectation Failed
Expect header cannot be met
418
I'm a teapot
Server refuses to brew coffee with teapot
422
Unprocessable Entity
Request well-formed but has semantic errors
423
Locked
Resource is locked (WebDAV)
424
Failed Dependency
Request failed due to previous request
425
Too Early
Server unwilling to risk early request
426
Upgrade Required
Client should switch protocols
428
Precondition Required
Request must be conditional
429
Too Many Requests
Rate limited, too many requests
431
Request Header Fields Too Large
Headers too large
451
Unavailable For Legal Reasons
Blocked for legal reasons

5xx 5xx 服务器错误

500
Internal Server Error
Generic server error
501
Not Implemented
Server does not support functionality
502
Bad Gateway
Invalid response from upstream server
503
Service Unavailable
Server not ready, often overloaded
504
Gateway Timeout
Gateway did not get response in time
505
HTTP Version Not Supported
HTTP version not supported
506
Variant Also Negotiates
Content negotiation error
507
Insufficient Storage
Server unable to store (WebDAV)
508
Loop Detected
Infinite loop detected (WebDAV)
510
Not Extended
Further extensions required
511
Network Authentication Required
Network authentication needed

状态码是协议契约,不是装饰

HTTP 状态码是机器可读的控制流,半个互联网都在依据它分支:浏览器决定是跟随重定向还是显示错误页,缓存和 CDN 决定是否存储响应,搜索爬虫决定把 URL 留在索引里还是剔除,HTTP 客户端库决定是否重试,监控系统决定要不要叫人起床。返回 200 却把错误消息塞进 JSON 正文 — 最常见的状态码反模式 — 会同时击溃所有这些系统:错误被缓存、被爬虫收录、客户端库上报成功,而你的错误率仪表盘在故障期间一路绿灯。 权威定义在 RFC 9110 "HTTP Semantics"(2022)里,它整合并取代了旧的 RFC 7231 家族。第一位数字承载契约:1xx 信息、2xx 成功、3xx 重定向、4xx 客户端出错、5xx 服务器出错。这个分类之所以承重,是因为规范里有一条明确规则:客户端收到不认识的代码时,必须按该类别的 x00 处理。没听过 429 的客户端必须把它当作普通的 400;未知的 599 按 500 处理。正是这条规则让新代码能进入生态而不破坏已部署的软件 — 也解释了为什么在错误类别里发明私有代码(比如用 470 报告"成功")会弄坏那些你控制不了的中间设备。4xx/5xx 的边界还是一次责任划分 — 它决定了谁被叫去救火。

把重定向做对:301、302、303、307、308

重定向代码之所以有五个,源于规范与浏览器之间一场二十年的分歧。HTTP/1.0 把 301 和 302 定义为保留方法:被 302 重定向的 POST 应该向新位置重新 POST。浏览器无视规定,把方法改写成 GET,而这个行为传播太广,已无法纠正。HTTP/1.1 没有对抗现实,而是把现实写进规范:创造了 303 See Other,意为"去 GET 那个资源"(防止刷新时重复提交表单的 POST-redirect-GET 模式的支柱);307 Temporary Redirect 恢复了原本的严格语义 — 同方法、同请求体、有保证;RFC 7538 在 2015 年用 308 Permanent Redirect 补全了矩阵 — 它是 301 的保留方法孪生。 所以心智模型是一个 2x2 矩阵:永久对临时,交叉可改方法对必须保留方法。301 和 302 是遗留角落(方法可能变成 GET);308 和 307 是严格角落。对接受 POST、PUT、DELETE 的 API 端点,这个区别绝非表面文章 — 用 301 重定向一次上传,许多客户端会悄悄把它变成没有请求体的 GET,请求数据就此蒸发。 "永久"是长牙的。浏览器激进地缓存 301 和 308,常常没有过期时间,于是一个配置错误的永久重定向会在服务器停止发送后,仍从本地缓存里持续触发 — 用户需要一次你无法远程发起的缓存清理。标准建议:有风险的重定向先用 302/307 上线,观察,再升格为 301/308。搜索引擎把 301/308 视为"把排名信号转移给新 URL",因此它们是域名迁移和 HTTPS 升级的正确选择,最好保持数月。
                 method may → GET   method preserved
permanent        301 Moved           308 Permanent Redirect
temporary        302 Found           307 Temporary Redirect
after POST       303 See Other  →  always GET (PRG pattern)

# Verify what a redirect really does:
curl -si -X POST https://example.com/old | head -3
HTTP/1.1 301 Moved Permanently
Location: https://example.com/new
# many clients will now GET /new — the POST body is gone

401、403 与 404:认证、授权与隐藏

名字破坏了语义:401 标着 "Unauthorized",实际意思却是未认证 — 服务器不知道你是谁。RFC 9110 把这个意图做进了结构:401 响应必须携带 WWW-Authenticate 头,告诉客户端该用哪种认证方案,因为 401 不是死胡同,而是一张"带上凭证再来"的邀请函。这就是浏览器遇到带 Basic 质询的 401 会弹出登录框的原因,也是设计良好的 API 客户端把 401 当作"刷新过期令牌并重放一次请求"触发器的原因。 403 Forbidden 是相反的处境:认证成功,身份明确,答案仍然是"不行"。令牌有效但缺少 scope;用户真实存在但不是管理员;资源存在但属于别人。关键的运维差异在于:用同样的凭证重试 403 毫无意义 — 见 403 就跑令牌刷新循环,是白白锤打认证服务器的缺陷。 规范还明确背书第三个选项:撒谎。对某资源返回 403 等于确认该资源存在,而存在本身有时就是机密 — 私有仓库的名字、用户账号的有无、内部管理路径。RFC 9110 允许想隐藏资源的服务器用 404 代替 403,GitHub 对你无权查看的私有仓库正是这么做的,广为人知。代价是可调试性(缺权限的正当用户会看到令人困惑的"not found"),所以这是一个真实的"安全对可支持性"权衡,最好有意识地决定。

重试与限流:429、503 与 Retry-After

429 Too Many Requests(定义于 RFC 6585,而非核心规范)是协议的背压阀门:请求被理解了,只是客户端发得太快。合格的 429 会带上 Retry-After 头,它接受两种格式 — 秒数增量(Retry-After: 30)或绝对的 HTTP-date — 客户端应当遵守它,而不是按自己的节奏重试。多数真实 API 还会补充配额遥测头(X-RateLimit-Limit / Remaining / Reset 家族,正在被标准化为 RateLimit 字段),让客户端在撞墙之前而非之后就能自我调速。 要不要重试取决于三个问题。这个失败可重试吗?5xx 一般可以,4xx 一般不行 — 请求本身有缺陷 — 例外是 408、429 以及(需谨慎的)425。这个方法重复执行安全吗?GET、PUT、DELETE 被定义为幂等;而中途超时的 POST 可能已经在看不见的地方成功了,盲目重试 POST 有重复扣款的风险 — 这正是支付 API 引入幂等键的原因。重试该怎么间隔?带抖动的指数退避 — 一群按同一固定节奏重试的客户端会重新同步成一波波冲击,把正在恢复的服务器再次压垮。 事故期间,5xx 三兄弟是一张分诊地图。502 Bad Gateway:代理连上了上游却收到垃圾 — 查应用进程(崩溃、OOM)。503 Service Unavailable:主动拒绝 — 过载、维护、健康检查失败,可能附带 Retry-After。504 Gateway Timeout:上游迟迟不响应 — 查慢查询、死锁、耗尽的连接池。
HTTP/1.1 429 Too Many Requests
Retry-After: 30
X-RateLimit-Limit: 100
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 1751414460

Retry decision cheat sheet:
408, 429, 5xx  → retry with exponential backoff + jitter
other 4xx      → do not retry; fix the request
POST           → only retry with an idempotency key

backoff: 1s → 2s → 4s → 8s (+ random jitter each step)

状态码与缓存:304、ETag 与默认可缓存清单

304 Not Modified 是唯一一个全部职责就是省带宽的状态码。流程是条件式重新验证:服务器给响应打上验证器 — ETag(不透明的版本标识)或 Last-Modified 日期 — 缓存副本过期后,客户端带着 If-None-Match 或 If-Modified-Since 再问一次。资源没变,服务器就回一个不带正文的 304,缓存把副本重新标记为新鲜,负载数据完全不过网。ETag 有两种强度 — 弱验证器(W/ 前缀)承诺语义等价,强验证器承诺字节一致(Range 请求必需)— 还有一个经典陷阱:默认从文件 inode 元数据派生的 ETag 在负载均衡器后的各台服务器上互不相同,悄悄毁掉重新验证。 更少人知道、也更危险的是:有些状态码默认可缓存。RFC 9110 把 200、203、204、206、300、301、308、404、405、410、414、501 指定为可启发式缓存 — 即使完全没有 Cache-Control 头,缓存也可以存储它们,并用诸如"距 Last-Modified 时间的十分之一"这样的启发式猜测新鲜度。没错,404 在清单上。生产故障模式:请求在你部署完成前到达,CDN 缓存了 404,文件明明已经存在却继续 404 — 直到有人手动清缓存。相反,302 和 307 不做启发式缓存,这正是临时重定向是安全实验、永久重定向是终身承诺的原因。 结论是永远不要依赖默认值:给每个响应 — 包括错误 — 发送显式的 Cache-Control,比如 404 配 60 秒 TTL、5xx 配 no-store,让失误短命。
# First request — server tags the response
HTTP/1.1 200 OK
ETag: "v42-a1b2c3"
Cache-Control: max-age=3600

# One hour later — conditional revalidation
GET /app.js HTTP/1.1
If-None-Match: "v42-a1b2c3"

HTTP/1.1 304 Not Modified        ← no body: bytes saved
ETag: "v42-a1b2c3"

# Cacheable WITHOUT any Cache-Control header (RFC 9110):
# 200 203 204 206 300 301 308 404 405 410 414 501
最后更新:

关于此工具

HTTP 状态码可检索参考,按 1xx-5xx 分类列出,每条含正式名称和简短说明,快速回答 "422 到底什么意思" 或 "应该返 401 还是 403"。

使用方法

  1. Type a code (404), partial name (gateway), or keyword (auth) into the search box.
  2. Browse the filtered list grouped by status class.
  3. Read the canonical name and one-line description for the matching codes.
  4. Use the colour coding to quickly spot 4xx (client error) vs 5xx (server error).
  5. Reference the result in your API design, log analysis, or error handling code.

常见用例

  • Choosing the right status code for a new REST API endpoint.
  • Investigating a strange status code (e.g., 418, 451) you saw in a server log.
  • Deciding between 401 Unauthorized and 403 Forbidden for an auth flow.
  • Documenting expected error responses in an OpenAPI / Swagger spec.
  • Understanding why a CDN returned 503 vs 504 during an outage.
  • Mapping HTTP errors to user-facing error messages with consistent semantics.

常见问题

Q. When should I return 401 vs 403?

A. 401 means "not authenticated, present credentials"; 403 means "authenticated but not allowed". If the client has no valid session, send 401. If they are logged in but lack permission, send 403.

Q. Is 422 the same as 400?

A. Both are 4xx, but 400 means the request itself is malformed (bad JSON, missing header) while 422 means the request is well-formed but semantically invalid (validation failed).

Q. Should I always use 200 for successful POSTs?

A. 201 Created is more precise when you create a new resource and 204 No Content when you succeed but return no body. 200 is correct when you do return a representation.

Q. What does 429 mean for rate limiting?

A. 429 Too Many Requests signals the client should slow down. Pair it with a Retry-After header so clients know when to try again.