Pack Camo

HTTP 状态码

全部 HTTP 状态码的含义与使用场景,支持搜索。

所有处理都在本地完成,不会上传任何内容。

2xx · 成功

200 OK

已在 IANA 注册默认可缓存

含义

The request succeeded. The body holds the result: the resource for GET, the outcome of the action for POST.

使用场景

The default success response. Prefer 201 when something was created and 204 when there is nothing to return.

定义于

RFC 9110 §15.3.1(在新标签页中打开)

状态行

HTTP/1.1 200 OK

HTTP/2 和 HTTP/3 只发送数字,放在 :status 伪头部中;原因短语(reason phrase)只存在于 HTTP/1.x。

每个 HTTP 状态码的含义,以及何时返回它

这是一份可搜索的参考,涵盖 IANA 注册表中所有标准 HTTP 响应状态码,从 <code>100 Continue</code> 到 <code>511 Network Authentication Required</code>。每个状态码都附有通俗易懂的解释、服务器或 API 应在何时返回它的建议、与之配套的响应头,以及定义它的 RFC 链接。常见的非官方状态码——nginx 的 <code>499</code>、Laravel 的 <code>419</code>、Cloudflare 的 <code>520</code>–<code>526</code>——也已收录并明确标注。可按数字、名称或关键词(如 "redirect" 或 "rate limit")搜索。

如何查找状态码

  1. 1输入状态码(404)、开头数字(40)、类别(4xx)、名称(teapot)或关键词(rate limit、cache、Retry-After)。
  2. 2用 1xx–5xx 筛选器把列表缩小到某一类别,或隐藏非官方状态码。
  3. 3用鼠标或方向键选择一个状态码,查看其含义、使用场景、相关响应头和规范出处。
  4. 4复制状态码或完整的状态行,或分享页面 URL:它以 #404 结尾,打开时直接定位到该状态码。

状态码的五个类别

客户端遇到无法识别的状态码时,会按其所属类别的 x00 码处理,因此未知的 499 会被当作 400,未知的 299 会被当作 200。正因如此,新增状态码不会破坏旧软件。

1xx 信息
在最终响应之前发送的临时响应:100 Continue、用于 WebSocket 的 101 Switching Protocols、用于预加载的 103 Early Hints。
2xx 成功
请求成功。200 OK 是默认值;201 Created 和 204 No Content 能更准确地说明发生了什么。
3xx 重定向
客户端需要去别处查找,通常是 Location 响应头中的 URL;如果是 304 Not Modified,则使用本地缓存副本。
4xx 客户端错误
请求本身有问题:格式错误、未认证、被禁止、请求的资源不存在,或请求过于频繁。原样重试不会有帮助。
5xx 服务器错误
请求可能没问题,但服务器或其后端出了故障。这类错误往往是暂时的,值得以退避(back-off)方式重试。

为 API 选择合适的状态码

大多数 API 只需要十几个状态码。成功时:带响应体用 200;创建了资源用 201 并附上 Location 头;任务稍后执行用 202;没有内容可返回用 204。客户端错误:请求格式错误用 400;格式正确但未通过校验用 422;缺少凭据或凭据无效用 401;凭据有效但权限不足用 403;资源不存在用 404;发生冲突(如邮箱重复)用 409;限流用 429。服务器错误:程序 bug 用 500,中间基础设施故障用 502、503 和 504。

无论返回哪个状态码,都应附上解释它的响应体。RFC 9457 "Problem Details"(application/problem+json)为这种响应体定义了标准结构,包含 type、title、status 和 detail 字段。切勿返回 200 却在响应体中放错误信息:缓存、监控和重试逻辑读取的都是状态码,而不是你的 JSON。要格式化这类响应体,可使用 JSON 格式化工具。

容易混淆的状态码

401 vs 403
401 Unauthorized 的意思是“我不知道你是谁”:请登录或发送有效的令牌。403 Forbidden 的意思是“我知道你是谁,但你不能这样做”。
301 vs 302 vs 307 vs 308
301 和 308 是永久重定向,会把搜索排名转移到新 URL;302 和 307 是临时重定向。307 和 308 保证请求方法和请求体不变,而浏览器在遇到 301 和 302 时会把 POST 改成 GET。
400 vs 422
400 用于服务器根本无法解析的请求;422 用于 JSON 有效但内容违反规则的情况,例如缺少必填字段。
404 vs 410
404 表示此处现在没有内容;410 表示这里曾经有内容但已被有意删除,搜索引擎会更快将其移出索引。
502 vs 504
两者都来自代理或负载均衡器。502 表示上游返回了无效响应或关闭了连接;504 表示上游没有及时响应。
500 vs 503
500 是意外故障,通常是 bug。503 是已知的临时状态(维护或过载),应附带 Retry-After 头。

状态码与 SEO

搜索引擎会仔细读取状态码。页面永久迁移时使用 301 或 308,让排名随之转移;302 则告诉搜索引擎继续索引旧 URL。对已不存在的页面返回真正的 404 或 410——返回 200 的“未找到”页面属于“软 404”(soft 404),会浪费抓取预算。维护期间返回 503 并附上 Retry-After,避免页面被移出索引。可以用 robots.txt 生成器控制爬虫可访问的内容。

状态码为 200、203、204、206、300、301、308、404、405、410、414、451 和 501 的响应,即使没有明确的新鲜度响应头,也可能被浏览器和 CDN 缓存,因此一个意外的 404 或 301 可能会长期存在;请为这些响应有意识地设置 Cache-Control。

日志中常见的非官方状态码

有些状态码不在 IANA 注册表中,但在实践中很常见。客户端在收到响应前断开连接时,nginx 会记录 499;nginx 不作应答直接关闭连接时记录 444。Cloudflare 无法从源服务器获得正常响应时返回 520–526:521 表示源服务器拒绝连接,522 表示连接超时,524 表示源服务器超过 100 秒才响应,525/526 表示与源服务器的 TLS 连接失败。Laravel 在 CSRF 令牌过期时返回 419。这些状态码在列表中标注为“非官方”,并可以隐藏。

常见问题

什么是 HTTP 状态码?
每个 HTTP 响应开头的三位数字,用来告诉客户端请求的处理结果。第一位数字表示类别:1xx 信息、2xx 成功、3xx 重定向、4xx 客户端错误、5xx 服务器错误。
401 和 403 有什么区别?
401 Unauthorized 表示请求没有有效凭据,登录可能会解决问题。403 Forbidden 表示服务器知道你是谁,但你没有权限,重新登录也无济于事。
重定向应该用 301 还是 302?
永久迁移时用 301(或 308),例如 URL 变更或更换域名;搜索引擎会把页面排名转移到新地址。原 URL 以后还会恢复使用时,用 302(或 307)。
429 Too Many Requests 是什么意思?
客户端触发了限流。请稍等再重试:如果响应带有 Retry-After 头,它会说明需要等待的秒数或截止时间。客户端应采用指数退避,而不是立即重试。
502 Bad Gateway 错误是什么原因造成的?
网站前面的代理、负载均衡器或 CDN 从后端服务器收到了无效响应——通常是因为应用崩溃、重启或关闭了连接。需要在服务器端解决,查看上游应用的日志。
499 状态码是什么?
nginx 特有的状态码,在 nginx 发送响应前客户端就关闭了连接时记录。客户端永远收不到它。大量出现 499 通常说明后端太慢,客户端等不及而放弃了。
418 I'm a teapot 是真实的状态码吗?
它最初是 RFC 2324(1998 年)中的愚人节玩笑,并不用于实际场景。但由于大量软件实现了它,RFC 9110 保留了 418,确保它永远不会被分配给其他用途。
HTTP 状态码一共有多少个?
IANA 注册表定义了约 63 个状态码,其中包括 306 和 305 等少数已保留或已弃用的状态码。理论上可用范围是 100 到 599,客户端会把任何未知状态码按其类别的 x00 码处理。