HTTP 状态码,免费
HTTP 响应状态码完整参考,含说明和使用场景。
HTTP 状态码类别
- 1xx(信息响应)· 请求已接收,正在处理中。
- 2xx(成功)· 请求已成功接收、理解并接受。
- 3xx(重定向)· 需要进一步操作才能完成请求。
- 4xx(客户端错误)· 请求语法错误或无法满足。
- 5xx(服务器错误)· 服务器无法满足合法请求。
301 和 302 有什么区别?
301 Moved Permanently 告诉客户端资源已永久移动 · 搜索引擎会转移排名权重。302 Found 是临时重定向 · 原 URL 保留排名。
何时使用 401,何时使用 403?
401 Unauthorized 意为「未认证」· 客户端需要提供凭证。403 Forbidden 意为「已认证但未授权」· 提供凭证也无济于事。
418 状态码是什么意思?
418「I'm a teapot」是 RFC 2324(Hyper Text Coffee Pot Control Protocol)中的一个愚人节玩笑。实际并未使用,但在开发者文化中广为人知。
三十年演进的标准
HTTP状态码经历了数代规范演进。RFC 1945(1996年5月)将HTTP/1.0标准化,奠定了1xx-5xx的基本分类。RFC 2616(1999年6月)发布了HTTP/1.1,成为此后十余年的权威参考。7230-7235系列(2014年6月)将HTTP/1.1按主题拆分为多个规范。当前合并标准为 RFC 9110《HTTP语义》(2022年6月),取代了7230-7235的拆分版本,是现代工作的正确引用文献。已分配代码的完整注册表位于 IANA的HTTP状态码注册表。
五大类别概览
- 1xx 信息性:临时响应。请求已收到,服务器正在继续处理。实践中较少见;对协议升级和现代
103 Early Hints有用(允许服务器在完整响应准备好之前预加载关键资源)。 - 2xx 成功:请求已收到、理解并接受。
200 OK是日常情况;201 Created用于资源创建;204 No Content用于无需返回内容的成功操作。 - 3xx 重定向:需要进一步操作。经典重定向(
301 Moved Permanently、302 Found、307 Temporary Redirect、308 Permanent Redirect)加上用于缓存验证的304 Not Modified。 - 4xx 客户端错误:客户端出了问题:语法错误、缺少认证、请求不存在的资源。这是真实流量中最大的类别。
- 5xx 服务端错误:服务器出了问题。请求是有效的,但服务器无法处理。这些是让值班工程师半夜惊醒的代码。
最容易混淆的「vs」比较
401 vs 403。最容易混淆的一对。401 Unauthorized 意味着「您尚未认证,请先登录」(名称在技术上有误导性,它关于的是认证而非授权)。403 Forbidden 意味着「您已认证,但不被允许执行此操作」,您的凭据有效,但不授予对该资源的访问权限。一个常见误用:对未认证请求返回 403,而正确做法是返回 401 搭配 WWW-Authenticate 响应头。
301 vs 302 vs 307 vs 308。两个维度:永久性/临时性,以及方法保留行为:
| 代码 | 永久? | 方法保留? | SEO排名信号 |
|---|---|---|---|
| 301 Moved Permanently | 是 | 历史上客户端会将POST → GET | 永久,排名传递给新URL |
| 302 Found | 否 | 历史上客户端会将POST → GET | 临时,原URL保留排名 |
| 307 Temporary Redirect | 否 | 严格,POST仍为POST | 与302相同 |
| 308 Permanent Redirect | 是 | 严格,POST仍为POST | 与301相同 |
若您因SEO目的重定向GET请求,301 是惯例选择。若您重定向POST或PUT请求并希望保留方法,则需要 307 或 308。
400 vs 422。400 Bad Request 用于语法格式错误的请求:无效JSON、缺少必需请求头、格式错误的查询参数。422 Unprocessable Entity(最初是WebDAV代码,已被REST API广泛采用)用于语法正确但存在语义问题的请求:JSON解析正常,但值不满足业务验证(订单数量为负、邮箱已被使用)。许多API同时使用两者。
502 vs 503 vs 504。三种不同的上游失败模式:
502 Bad Gateway:代理/网关从上游服务器收到了无效响应。503 Service Unavailable:服务器过载或正在维护。通常搭配Retry-After响应头使用。504 Gateway Timeout:上游服务器未及时响应。
404 vs 410。404 Not Found 表示「我们不知道该资源是否存在」。410 Gone 表示「该资源曾经存在,现已被永久删除」。SEO影响:Google将 410 视为内容永久不可用的更强信号,比 404 更快将其从索引中移除。
REST API惯例
现代REST API在状态码的使用上形成了相当一致的惯例:
| 方法 | 正常路径 | 常见错误 |
|---|---|---|
| GET | 带响应体的 200 OK,或缓存有效时的 304 Not Modified | 资源不存在时 404,无权访问时 403 |
| POST(创建) | 201 Created,响应头中含指向新资源的 Location | 请求体格式错误时 400,验证错误时 422,冲突时 409 |
| PUT(替换)/ PATCH(更新) | 带更新后响应体的 200 OK,或 204 No Content | 资源不存在时 404,版本冲突时 409 |
| DELETE | 204 No Content(或带删除确认的 200) | 资源不存在时 404 |
| 任何(限流) | - | 429 Too Many Requests,带 Retry-After 响应头 |
| 任何(认证) | - | 未认证时 401,已认证但无权限时 403 |
SEO影响
200 OK:Google正常收录该页面。301 Moved Permanently:Google将收录的URL更新为新URL并传递排名信号。302 Found/307 Temporary Redirect:Google保持原URL的收录状态;排名留在原URL。308 Permanent Redirect:Google像对待301一样处理:排名传递。304 Not Modified:被Googlebot用于条件请求;表示缓存内容可以复用。404 Not Found:Google在几次抓取后将该URL从索引中移除。410 Gone:Google比处理404更快地移除该URL;「永久消失」信号更强。503 Service Unavailable搭配Retry-After:告知Googlebot稍后再来。维护窗口期间使用;避免将503用于真正的错误(持续的503会被Google解读为禁止抓取的指令)。5xx持续出现:Google降低抓取频率,最终可能将该URL从索引中完全移除。
著名与文化代码
418 I'm a teapot:RFC 2324(超文本咖啡壶控制协议,1998年4月1日)的愚人节玩笑。2017年IETF提议将其从规范中移除时,「Save 418」运动成功将其保留。部分API将其用作「这不是真实接口」的标记;其余情况无害。451 Unavailable For Legal Reasons:RFC 7725(2015年),以Ray Bradbury的《华氏451度》命名。当内容因法院命令或政府要求而被屏蔽时返回。- Cloudflare的520-527系列:非标准代码,Cloudflare用于指示特定的上游服务器连接失败。Cloudflare背后的网站出现问题时常见。
- Nginx的
444 No Response:Nginx专有,当服务器在不发送任何响应的情况下关闭连接时返回。 - Twitter历史上的
420 Enhance Your Calm:Twitter早期API曾使用的限流代码,现已移除;已被标准429取代。
常见错误
- 对错误响应使用
200 OK。将{"error": "not found"}与200状态码一起返回会混淆所有缓存层、监控工具和客户端SDK。请使用正确的状态码。 - 对未认证请求返回
403。正确代码是401搭配WWW-Authenticate响应头。 - 误将
302当成301使用。若迁移是永久性的,搜索引擎需要301来传递排名。302会使原URL继续被索引。 - 对POST/PUT重定向使用
301或302。历史上这允许客户端将方法改为GET。307和308会严格保留原始方法。 - 返回
500而非503。若服务器过载或正在维护,503搭配Retry-After才是正确信号,无论对客户端还是Googlebot。 - 对永久删除的页面使用
404。410 Gone是更强的信号,会更快从搜索引擎索引中移除。 - 遗漏
Location响应头(在201和3xx响应中)。Location响应头告知客户端新资源的位置或重定向目标。没有它,客户端无法导航。
更多常见问题
何时应返回 422 而非 400?
400 Bad Request 表示请求本身格式错误:无效JSON、缺少必需响应头、格式错误的查询参数。422 Unprocessable Entity 表示请求格式正确,但包含阻止处理的语义错误:数量字段设为负数、邮箱地址已被使用、仅限未来日期的字段收到了过去的日期。现代REST API惯例在此达成共识,大多数大型API(GitHub、Stripe、Twilio)将 422 用于验证错误。
为什么Cloudflare有时会返回520、521、522…?
520-527代码是Cloudflare专有的,表示其边缘节点无法到达您的源服务器的不同方式。520 是通用的「网络服务器返回了未知错误」信号;521 表示源服务器拒绝了连接;522 是到源服务器的连接超时;524 表示源服务器响应太慢。这些代码不在IANA注册表中,但在Cloudflare背后的网站出现后端问题时经常遇到。
浏览器会显示API返回的状态码吗?
会。打开开发者工具 → Network(网络)标签页,点击请求,查看「状态」列。浏览器还会为某些代码显示通用页面(Chrome连接失败时的恐龙游戏、标准的404/500页面);但实际数字代码始终在响应中。
什么是 103 Early Hints?
一种相对较新的(RFC 8297,2017年) 1xx 代码,允许服务器在完整响应准备好之前发送 Link: rel=preload 响应头,告知浏览器提前获取关键资源(CSS、字体、图片)。现已被Chrome支持,并由Cloudflare、Fastly和其他CDN作为性能优化部署。
我可以自定义状态码吗?
技术上可以(HTTP允许100-599范围内的任何3位数字代码。实际上不建议)客户端、代理和缓存会按第一位数字处理未知代码(因此 4xx = 通用客户端错误,5xx = 服务器错误)。部分供应商这样做(Cloudflare的520系列、Nginx的444),但除非您控制通信的两端,否则请遵循IANA注册表。自创 299 不会破坏任何东西,但也不会传递任何信息。
为什么叫「状态码」而不是「错误码」?
因为大多数代码不是错误。200 OK 是世界上被返回最多的状态码,意味着「一切正常」。这些代码传递的是请求的状态:成功、重定向、客户端错误、服务器错误。将它们称为「错误码」会让人偏向关注那些被记录和注意到的负面情况;成功代码在每一微秒都在默默完成它们的工作。