⌘K 切换工具
NETWORK · HTTP

HTTP状态码参考

浏览HTTP状态码及其说明。

local
http-status
CodeNameClassMeaning
100ContinueInformationalThe client should continue with its request.
101Switching ProtocolsInformationalThe server is switching protocols as requested.
200OKSuccessThe request succeeded.
201CreatedSuccessThe request succeeded and a new resource was created.
202AcceptedSuccessThe request was accepted but not yet processed.
204No ContentSuccessSuccess, but there is no content to return.
206Partial ContentSuccessThe server delivered part of the resource (range request).
301Moved PermanentlyRedirectionThe resource has permanently moved to a new URL.
302FoundRedirectionThe resource is temporarily at a different URL.
304Not ModifiedRedirectionThe cached version is still valid.
307Temporary RedirectRedirectionTemporary redirect that preserves the method.
308Permanent RedirectRedirectionPermanent redirect that preserves the method.
400Bad RequestClient ErrorThe server could not understand the request.
401UnauthorizedClient ErrorAuthentication is required and has failed or not been provided.
403ForbiddenClient ErrorThe server understood but refuses to authorize the request.
404Not FoundClient ErrorThe requested resource could not be found.
405Method Not AllowedClient ErrorThe HTTP method is not supported for this resource.
408Request TimeoutClient ErrorThe server timed out waiting for the request.
409ConflictClient ErrorThe request conflicts with the current state of the resource.
410GoneClient ErrorThe resource is permanently gone.
418I'm a teapotClient ErrorAn April Fools joke from RFC 2324.
422Unprocessable EntityClient ErrorThe request was well-formed but semantically invalid.
429Too Many RequestsClient ErrorThe client has sent too many requests (rate limited).
500Internal Server ErrorServer ErrorA generic server-side error occurred.
501Not ImplementedServer ErrorThe server does not support the requested functionality.
502Bad GatewayServer ErrorAn upstream server returned an invalid response.
503Service UnavailableServer ErrorThe server is temporarily overloaded or down.
504Gateway TimeoutServer ErrorAn upstream server did not respond in time.
§01 关于此工具

概述

状态码是服务器对「发生了什么」给出的一句话总结,而挑错一个的后果,远不只是显得不够整洁而已:它会改变客户端是否重试、缓存是否存储这个响应、爬虫是否继续保留这个 URL,以及代理会不会把这个请求再处理一次。

这是一份可搜索的参考,覆盖的是你实际会遇到的那些状态码,而每一条给出的都是实用的区分要点,而不是把规范原文重述一遍。

使用方法

输入一个数字(404)或者名称的一部分(gateway)来过滤清单。匹配同时作用于这两个字段,所以 too many429 会找到同一条。

五个类别

类别含义客户端该怎么做
1xx信息性——请求仍在进行中继续等
2xx成功使用这个响应
3xx重定向——资源在别处,或者根本没有变化跟过去,或者用缓存
4xx客户端错误——请求本身就是问题所在不要原样重试
5xx服务器错误——请求本身可能没有问题带退避地重试

4xx5xx 之间的划分在实践中是最要紧的一条,因为它直接决定了重试行为。一台对畸形请求返回 500 的服务器,会被每一个带重试策略的守规矩客户端一遍又一遍地送来同一个畸形请求。只有返回 400 才能终止这个循环。

值得分清的那些区别

200 加一个装在正文里的错误。 这在 API 里很常见,而且几乎总是错的。你和客户端之间的每一层——缓存、代理、监控、重试逻辑——读的都是状态码,而不是你的 JSON。一个返回 200 的错误,对它们全都是不可见的。

创建时该用 201 还是 200 201 应该携带一个指向新资源的 Location 头。那才是客户端真正会用到的部分;单独一个状态码本身添的东西不多。

202 Accepted。 对于那些你排进队列而不是当场做完的工作,这是正确的答案。它是一个承诺,所以它需要告诉客户端去哪里查询进展——一个状态 URL,或者一个任务 id。

204 No Content。 表示成功,并且刻意不带正文,典型场景是 DELETE,或者一个不返回任何内容的 PUT。它必须完全没有正文,而不是一个空的 JSON 对象。

304 Not Modified。 这是对一个条件请求的响应,其 ETagLast-Modified 仍然匹配。它不带正文,而这正是它的全部意义所在:客户端已经有那些字节了。如果你从来不返回 304,那么每一次重新验证都会把整个资源再传一遍。

400 还是 422 400 用于服务器根本无法解析的请求——畸形的 JSON、缺少某个必需参数。422 用于那些解析得干干净净、但校验失败的请求。这个区分告诉客户端,它该去修的是自己的序列化,还是自己的数据。

405 Method Not Allowed。 必须包含一个 Allow 头,列出哪些方法被接受的。没有它,客户端只是被拒绝了,却拿不到任何前进的路径。

409 Conflict。 用于那些无法应用到当前状态的请求——针对一个过期版本的编辑、一个违反唯一约束的重复项。它不是一个泛用的「有什么地方不对」。

410 Gone。 一个更强的 404:这个东西曾经存在,而且不会回来了。爬虫丢掉 410 比丢掉 404 更快,而对于你刻意移除的内容来说,这正是你想要的效果。

429 Too Many Requests。 需要配上 Retry-After。没有它,客户端只能靠猜,而且会猜得很糟——通常就是立刻重试。

502503504 之间的区别。 502 意味着某个上游返回了一个无效的响应。503 意味着这台服务器自己不可用,典型的情况是过载或者正在维护。504 意味着某个上游没有及时给出应答。它们指向的是三个完全不同的地方,而把它们互换着用,会让一次故障变得更难定位。

示例

  • 爬虫一直在请求一个已经删除的页面。 返回 410 而不是 404
  • 客户端在猛敲一个正在失败的端点。 检查这个失败是不是把实际上属于 4xx 的情况返回成了 5xx
  • 一次表单提交在重定向之后把数据丢了。 这个重定向大概是 301302;改成 308307
  • CDN 不肯缓存某个响应。 2xx3xx 默认是可缓存的;大多数 4xx 不可缓存,而 5xx 永远都不该被缓存。
  • 一个 API 返回 200,客户端无视了失败。 它们不是在无视——根本就没有东西告诉过它们。

说明

418 I'm a teapot 是真实存在的,在「它已被登记并且被永久保留」这个意义上。它出自一份愚人节的 RFC,之所以出现在这份清单里,是因为人们真的会去查它。

不在登记表里的状态码同样是合法的。客户端必须按类别去处理任何一个未知的状态码,所以一个自定义的 299 会被当成成功,而一个自定义的 599 会被当成服务器错误。真要去用它们,通常并不值得换来那份困惑。

这里的清单覆盖的是实际还在使用中的那些状态码。完整的登记表由 IANA 维护,其中还包含 WebDAV 以及其他扩展所用的状态码,而一个典型的 Web 服务永远都不会返回它们。

想看某个线上 URL 实际返回哪些状态码,包括它的整条重定向链,请用 HTTP 头信息检查

FAQ
这个工具会把任何东西发送出去吗?
不会。状态码清单本身就是页面的一部分。加载完成之后它可以离线工作,你输入的内容不会离开浏览器。
401 和 403 有什么区别?
401 意味着这个请求没有通过认证——服务器不知道你是谁,而一份有效的凭据会改变这个答案。403 意味着它确实知道你是谁,而答案仍然是不行。401 必须带一个 WWW-Authenticate 头说明该如何认证;403 没有任何可以给出的东西。
什么时候该用 404 而不是 403?
当承认这个资源存在本身就会泄露信息的时候,用 404。对 /users/42 返回 403,等于告诉攻击者用户 42 确实存在;而 404 不会。这是一个刻意说出的谎,而对授权敏感的资源来说,它是正确的那一个。
哪些重定向会保留请求方法?
307 和 308。客户端历史上在跟随 301 和 302 时会把 POST 转成 GET,而这个行为至今仍然普遍存在,所以只要可能涉及 POST,永久搬迁就用 308,临时搬迁就用 307。
429 和 503 是一回事吗?
不是。429 意味着这个客户端发了太多请求,应该慢下来。503 意味着服务器整体现在没法为任何人服务。两者都应该携带 Retry-After,而把它们混用会让客户端的退避行为出错。