HTTP 状态码

所有已注册的 HTTP 状态码:含义、出现场景以及定义出处。

100ContinueThe server received the request headers and the client should send the body.
101Switching ProtocolsThe server is switching to the protocol the client asked for in the Upgrade header.
102ProcessingThe server accepted the request and is still working on it.
103Early HintsHeaders sent ahead of the final response so the client can start preloading resources.
104Upload Resumption SupportedThe server supports resuming this upload if it is interrupted.
200OKThe request succeeded.
201CreatedThe request succeeded and created a new resource.
202AcceptedThe request was accepted for processing, which hasn't finished.
203Non-Authoritative InformationSuccess, but a proxy changed the response the origin server sent.
204No ContentThe request succeeded and there is no body.
205Reset ContentSuccess; the client should reset the form or view that sent the request.
206Partial ContentThe response holds only the byte range the client asked for.
207Multi-StatusThe body holds separate status codes for several operations.
208Already ReportedMembers of this collection were already listed earlier in the same 207 response.
226IM UsedThe response is a delta applied to the current instance, not the full resource.
300Multiple ChoicesThe resource has several representations and the client should choose one.
301Moved PermanentlyThe resource has a new permanent URL, given in the Location header.
302FoundThe resource is temporarily at the URL in the Location header.
303See OtherThe result is at another URL, which the client should fetch with GET.
304Not ModifiedThe cached copy is still valid, so no body is sent.
305Use ProxyThe resource must be accessed through the proxy in the Location header.
306(Unused)Reserved; it was once used for Switch Proxy and is no longer used.
307Temporary RedirectThe resource is temporarily at another URL; repeat the request there with the same method and body.
308Permanent RedirectThe resource has moved permanently; repeat the request at the new URL with the same method and body.
400Bad RequestThe server can't process the request because it is malformed.
401UnauthorizedThe request has no valid credentials for this resource.
402Payment RequiredReserved for future use.
403ForbiddenThe server understood the request but refuses to allow it.
404Not FoundThe server has nothing at this URL.
405Method Not AllowedThe resource exists but doesn't support this HTTP method.
406Not AcceptableThe server can't produce a response in any format the Accept headers allow.
407Proxy Authentication RequiredThe client must authenticate with the proxy first.
408Request TimeoutThe server gave up waiting for the client to finish sending the request.
409ConflictThe request conflicts with the current state of the resource.
410GoneThe resource existed but has been removed permanently.
411Length RequiredThe server needs a Content-Length header.
412Precondition FailedA condition in the request headers, such as If-Match, is false.
413Content Too LargeThe request body is larger than the server accepts.
414URI Too LongThe URL is longer than the server accepts.
415Unsupported Media TypeThe server doesn't accept the body's format.
416Range Not SatisfiableThe requested byte range is outside the resource.
417Expectation FailedThe server can't meet the Expect header.
418I'm a teapotA joke code from RFC 2324, kept reserved as "(Unused)" because so much software already recognizes it.
421Misdirected RequestThe request reached a server that can't answer for this host.
422Unprocessable ContentThe request is well formed but its content fails validation.
423LockedThe resource is locked.
424Failed DependencyThe request failed because a request it depended on failed.
425Too EarlyThe server won't process a request that might be replayed.
426Upgrade RequiredThe client must switch to another protocol, named in the Upgrade header.
428Precondition RequiredThe server requires a conditional request, such as one with If-Match.
429Too Many RequestsThe client has sent too many requests in a given time and is being rate limited.
431Request Header Fields Too LargeThe headers, or one header, are too large.
451Unavailable For Legal ReasonsThe resource can't be served for legal reasons.
500Internal Server ErrorThe server hit an unexpected condition.
501Not ImplementedThe server doesn't support the functionality needed, such as the request method.
502Bad GatewayA gateway or proxy got an invalid response from the server behind it.
503Service UnavailableThe server can't handle the request right now.
504Gateway TimeoutA gateway or proxy didn't get a response from the server behind it in time.
505HTTP Version Not SupportedThe server doesn't support the HTTP version of the request.
506Variant Also NegotiatesContent negotiation is misconfigured on the server.
507Insufficient StorageThe server can't store what it needs to complete the request.
508Loop DetectedThe server found an infinite loop while processing the request.
510Not ExtendedThe request needs an HTTP extension the server requires.
511Network Authentication RequiredThe client must authenticate to get network access.
419Page ExpiredLaravelThe CSRF token is missing or expired.
420Enhance Your CalmTwitter (historical)The client is being rate limited.
444No Responsenginxnginx closed the connection without sending a response.
494Request Header Too Largenginxnginx's code for headers over its buffer limits.
495SSL Certificate ErrornginxThe client certificate failed verification.
496SSL Certificate RequirednginxA required client certificate wasn't sent.
497HTTP Request Sent to HTTPS PortnginxA plain HTTP request reached a port that expects TLS.
499Client Closed RequestnginxThe client closed the connection before nginx sent the response.
509Bandwidth Limit ExceededApache / cPanelThe site has used up its bandwidth allowance.
520Web Server Returned an Unknown ErrorCloudflareThe origin server returned something Cloudflare couldn't use.
521Web Server Is DownCloudflareThe origin server refused Cloudflare's connection.
522Connection Timed OutCloudflareCloudflare couldn't establish a TCP connection to the origin in time.
523Origin Is UnreachableCloudflareCloudflare can't reach the origin server.
524A Timeout OccurredCloudflareCloudflare connected to the origin, but it didn't respond in time.
525SSL Handshake FailedCloudflareThe TLS handshake between Cloudflare and the origin failed.
526Invalid SSL CertificateCloudflareCloudflare couldn't validate the origin's certificate.
530Origin DNS ErrorCloudflareCloudflare returns 530 together with a 1xxx error, most often 1016 (origin DNS error).

Select a code

Pick a code from the list to see when it is used, the specification that defines it and a command to try it. Use the arrow keys to move through the list.
64 registered codes · 17 unofficial

什么是 HTTP 状态码?

每个 HTTP 响应都以一个三位数的状态码开头,说明请求的处理结果。第一位数字表示类别:1xx 表示信息,2xx 表示成功,3xx 表示重定向,4xx 表示请求有误,5xx 表示服务器出错。

这些状态码定义在 RFC 9110(HTTP Semantics,于 2022 年取代 RFC 7231)以及其他一些 RFC 中,例如定义 429 Too Many Requests 的 RFC 6585。IANA 维护着官方注册表。RFC 9110 重命名了两个状态码:413 现在叫 Content Too Large(原名 Payload Too Large),422 叫 Unprocessable Content(原名 Unprocessable Entity)。编号和行为都没有变化。

你遇到的一些状态码并不在注册表中。客户端在响应准备好之前关闭连接时,nginx 会记录 499;Cloudflare 无法从源服务器获得可用响应时会返回 520 到 526;表单的 CSRF 令牌过期时,Laravel 会返回 419。这些状态码单独列出,并标记为非官方。

状态码是 API 测试首先要检查的内容,因为响应的其余部分都取决于它。201 Created 表示 POST 创建了新资源,404 表示资源不存在,500 表示服务器出错,此时响应体可能是一个错误页面,而不是你期望的 JSON。

使用方法

  1. 1浏览按 1xx 到 5xx 分组的列表(非官方状态码在最后),或用类别按钮进行筛选。
  2. 2按编号、名称或现象搜索,例如 404、5xx、redirect、timeout,或旧名称 Unprocessable Entity。在页面任意位置按 / 即可跳到搜索框。
  3. 3选中一个状态码,或用方向键在列表中移动,即可查看它的含义、出现场景、定义它的规范,以及可供对比的相关状态码。
  4. 4复制 Try it 下的 curl 命令,让 testingapis.com 的状态端点返回该状态码;也可以复制链接:/zh/tools/http-status/#429 会直接打开 429。

问题排查

明明发送了令牌,却返回 401
令牌已过期、格式错误、放在了错误的请求头中,或者缺少 Bearer 前缀。响应头 WWW-Authenticate 通常会说明是哪种情况。如果返回的是 403,则表示令牌有效但没有权限。
发送 JSON 请求体却返回 415
请求中没有 Content-Type: application/json 头,所以服务器不会把请求体当作 JSON。除非你设置了这个头,否则 curl 的 -d 会发送 application/x-www-form-urlencoded。
重定向后 POST 变成了 GET
客户端在跟随 301 和 302 时,会以不带请求体的 GET 重新发送请求。需要保留请求方法的服务器应返回 307 或 308。
负载均衡器返回 502 或 504
应用前面的代理没有收到有效响应:应用崩溃或关闭连接时返回 502,应用响应时间超过代理的超时设置时返回 504。应用自身的日志会显示原因。
nginx 日志中出现 499
客户端在响应准备好之前放弃了:用户离开了页面,或者客户端、上游代理超时了。最常见的原因是后端请求太慢。

常见问题

401 和 403 有什么区别?

401 Unauthorized 表示服务器不知道你是谁:凭据缺失、过期或错误。403 Forbidden 表示服务器知道你是谁,但该身份无权执行此操作。重新登录可以解决 401,但解决不了 403。

对于无效输入,API 应该返回 400 还是 422?

两者都有人用。常见的约定是:服务器根本无法读取的请求(例如格式错误的 JSON)返回 400,格式正确但违反规则的数据(例如缺少必填字段或邮箱无效)返回 422。

502、503 和 504 有什么区别?

这三个通常都来自应用前面的代理或负载均衡器。502 Bad Gateway 表示它从后端服务器收到了无效响应,503 Service Unavailable 表示服务过载或正在维护,504 Gateway Timeout 表示后端服务器没有及时响应。

应该使用哪个重定向状态码?

301 和 308 是永久重定向,302 和 307 是临时重定向。307 和 308 要求客户端用相同的方法和请求体重新发送请求,而客户端在遇到 301 或 302 时通常会把 POST 变成 GET。POST 之后要把客户端引导到结果页面,请使用 303 See Other。

418 I'm a teapot 是真实的状态码吗?

它来自 RFC 2324,这是 1998 年的一个愚人节玩笑,内容是如何控制咖啡壶。由于大量软件已经能识别它,RFC 9110 把 418 列为“未使用但保留”。它并不用于真正的错误。

如何测试我的应用对某个状态码的处理?

调用一个能返回指定状态码的端点。GET https://api.testingapis.com/api/status/503 会返回 503,并附带该状态通常携带的响应头,例如 Retry-After。200 到 599 之间的任何状态码都可以。