在线工具集

HTTP 状态码全解:每个 3 位码什么含义、何时返回

从 1xx 信息响应、2xx 成功、3xx 重定向到 4xx 客户端错误和 5xx 服务器错误,掌握 HTTP 状态码在 SEO、限流、API 设计中的实际应用。

✍️ XTechTools 编辑团队 · 📅 发布 2026-04-29 · 🔄 更新 2026-06-14 · ⏱ 约 19 分钟阅读 ·→ 立即使用 HTTP 状态码

HTTP 状态码是 Web 通信的"信号灯"。客户端(浏览器、手机应用)向服务器发起请求,服务器用一个三位数来回应:"成功收到了"、"地址改了"、"你没权限"、"我崩了"等。200 对应成功,404 对应资源不存在,这些大家都知道。但 301 和 302 的区别是什么?为什么 SEO 关心状态码?限流为什么用 429?本指南逐一解答,并附上在实际应用中的代码示例。

1xx 信息响应(100-199):客户端与服务器的握手

1xx 很少在日常应用中见到,浏览器和服务器通常会自动处理,开发者几乎无须关心。这些状态码主要用于长连接和协议切换场景。

常见的几个: - 100 Continue:客户端发送大请求前问「我能发吗?」,服务器回应「可以」继续发送请求体。常见于上传大文件时的 Expect: 100-continue 头。 - 101 Switching Protocols:切换协议,最常见的是 HTTP 升级为 WebSocket(HTTP GET 请求 + Upgrade header)。 - 102 Processing(WebDAV):服务器还在处理,别断开连接。现代 API 已被 202 Accepted 取代。 - 103 Early Hints(实验性):允许服务器在最终响应前发送 Link header 预加载资源。

实际开发中:你几乎不用手动返回 1xx,框架自动处理。Nginx、Express 等中间件默认管理这些状态。除非你在写底层 HTTP 服务器或 WebSocket 库,否则不用深入理解细节。

2xx 成功响应(200-299):请求处理成功

客户端请求成功处理,服务器返回数据或确认操作完成。不同的 2xx 码细分了成功的具体情况。

最常用的: - 200 OK:请求成功,返回完整响应体(HTML、JSON 等)。这是 90% 的请求的正常响应。用于 GET(查询数据)、PUT(更新数据)、PATCH(部分更新)。 - 201 Created:资源创建成功(通常用 POST 返回),Location header 包含新资源的 URL。例如 POST /users 返回 201,Location header 为 /users/123,客户端可以通过这个 URL 查询新建的资源。 - 202 Accepted:请求已接受但还未完成(异步操作),返回 task_id 或 polling_url。例如视频转码服务:POST 返回 202,响应体包含 {"task_id": "abc123"} 和一个状态查询地址。 - 204 No Content:请求成功但没有内容返回,常用于 DELETE 操作或 PUT 更新无需回传数据。特别是删除用户后,你不需要再看一遍用户信息。 - 205 Reset Content:要求客户端重置表单(HTML form),现代 API 极少用。这是个遗留状态码。 - 206 Partial Content:分块传输,客户端用 Range header 请求部分资源(视频拖拽进度条就是这个)。响应包含 Content-Range header 标明返回的字节范围。

API 设计建议:POST 创建资源用 201(更明确);DELETE 成功用 204(没有内容返回);GET 和 PUT 通常 200;异步操作用 202。这样客户端能准确识别操作的结果类型。

3xx 重定向(300-399):SEO 的生死攸关

资源地址改变或需要进一步操作,客户端按 Location header 重新请求新地址。这是最容易搞混、也最容易影响 SEO 的一类状态码。

最关键的几个(对 SEO 影响巨大):

301 Moved Permanently(永久重定向): - 浏览器和搜索引擎都会更新书签和索引,下次直接访问新地址 - 用途:域名迁移(old-domain.com → new-domain.com)、URL 结构调整(/product?id=1 → /products/1) - SEO:旧页面的权重、关键词排名、外链价值全转到新地址,SEO 无损失 - HTTP 方法:规范中 GET 保持 GET,POST 变 GET(但很多浏览器和库不遵守) - 缓存:浏览器会缓存 301 重定向,再次访问旧地址会直接跳转,不会再问服务器

302 Found(临时重定向): - 告诉搜索引擎这是临时的,保留旧地址的索引和权重,不转移到新地址 - 用途:网站维护(临时关闭,维护后恢复到原地址)、A/B 测试(某些用户重定向到测试页面) - SEO:搜索引擎继续爬旧地址,不转移权重。适合那些不想改变 SEO 排名的重定向 - HTTP 方法:规范说保持原方法,但实现不同,浏览器通常变 GET

307 Temporary Redirect: - 含义与 302 相同,但 HTTP 方法严格保持。POST → POST,GET → GET - 用途:比 302 更严格和可预测,常用于 REST API。如果 POST 到一个临时地址,307 保证重定向后仍是 POST,不会意外变成 GET

308 Permanent Redirect: - 含义与 301 相同,但 HTTP 方法严格保持。POST → POST - 用途:API 端点迁移。从 /api/v1/users 迁移到 /api/v2/users,用 308 保证 POST 请求仍为 POST

303 See Other: - 用新 URL 的 GET 方法查询结果(常见于 POST-Redirect-GET 模式) - 例如:用户 POST 表单提交数据,服务器处理后用 303 重定向到结果页面(GET 方法)

实际建议清单: - 网站永久改版或域名迁移:用 301 - 临时下线维护:用 302 或 307 - API 端点永久迁移:用 308 - POST 表单提交后显示结果:用 303 - 一般 API 临时重定向:用 307(更可预测)

4xx 客户端错误(400-499):请求不当或无权限

请求有问题,服务器无法或拒绝处理。这类错误通常要求客户端修正请求。

常见的: - 400 Bad Request:请求格式错误(JSON 语法错、缺必填字段、Content-Type 错误)。用于无法解析的请求。 - 401 Unauthorized:未认证,需提供有效身份(如 API token、用户名密码)。客户端还没登录或 token 过期。与 403 的区别:401 说你没登录;403 说你登录了但没权限。 - 403 Forbidden:已认证但无权限访问(如普通用户访问管理员后台、学生访问教师专属资源)。返回 403 暗示资源存在,只是你看不到。 - 404 Not Found:资源不存在(拼错 URL、删除的页面、不存在的 ID)。这是最常见的错误。 - 405 Method Not Allowed:HTTP 方法不支持(如对 /api/users POST 用了 DELETE,而服务器端点没定义 DELETE)。应包含 Allow header 列举支持的方法。 - 409 Conflict:请求冲突(如创建用户但邮箱已存在、并发修改同一资源导致版本冲突)。常见于 PUT 操作当资源被别人修改过。 - 410 Gone:资源已被永久删除,不同于 404(也许以后会恢复)。 - 422 Unprocessable Entity:请求格式合法但业务逻辑不通(如年龄输入 -5、日期格式错)。与 400 的区别:400 是语法错;422 是内容语义不合理。 - 429 Too Many Requests:限流,请求过于频繁。详见下面专章。 - 451 Unavailable For Legal Reasons:资源因法律原因不可用(如版权、政治审查),主要见于国际应用。

关键的 header: - WWW-Authenticate(401):告诉客户端怎么认证。例如 WWW-Authenticate: Bearer realm="api" - Retry-After(429、503):告诉客户端多久后重试(单位秒或日期) - Allow(405):列举支持的 HTTP 方法。例如 Allow: GET, POST, PUT

HTTP 429 限流详解与实现

当 API 调用频率过高,服务器返回 429 拒绝请求,防止滥用和 DDoS 攻击。这是现代 API 的必需功能。

常见限流策略

1. 令牌桶(Token Bucket): - 原理:固定速率放入令牌(如每秒 100 个),每次请求消耗 1 个令牌。桶满时丢弃新令牌,请求无令牌时返回 429 - 优点:允许突发流量(如果桶里有多个令牌,一次可以处理多个请求) - 适用:API 限流、图片/视频服务的上传限流

2. 滑动时间窗(Sliding Window): - 原理:记录过去 1 分钟内的请求数,超过阈值(如 1000 次)返回 429。移除时间窗外的请求记录 - 优点:公平精确,没有边界问题 - 适用:按分钟/小时的配额限制

3. 漏桶(Leaky Bucket): - 原理:请求进桶,以恒定速率漏出并处理。桶满时拒绝新请求(429) - 优点:速率恒定,避免突发 - 适用:数据库连接池、队列处理

返回示例(Node.js + Express): `` router.get('/api/data', rateLimitMiddleware, (req, res) => { if (req.rateLimitExceeded) { res.status(429); res.set('Retry-After', '60'); res.json({ error: 'Too Many Requests', message: 'Please wait 60 seconds' }); return; } res.json({ data: '...' }); }); ``

在 Nginx 中的配置: `` limit_req_zone $binary_remote_addr zone=api:10m rate=10r/s; server { location /api/ { limit_req zone=api burst=20 nodelay; } } ``

这表示每秒 10 个请求,允许 20 个请求的突发。超出时返回 429。

应用场景: - 免费 API:每个用户每小时 100 次 - 认证用户:每个用户每小时 1000 次 - 高级用户:无限制 - 公开端点(登录、注册):每 IP 每分钟 5 次(防暴力攻击)

5xx 服务器错误(500-599)与故障排查

服务器内部出错或暂时无法处理请求。这些错误通常需要管理员介入修复。

常见的: - 500 Internal Server Error:最通用的服务器错(代码 bug、未捕获异常、数据库连接失败、内存不足)。错误原因隐藏,只告诉客户端「我坏了」。 - 501 Not Implemented:服务器不支持此功能(如接收到 HTTP 方法 TRACE 但没实现)。罕见。 - 502 Bad Gateway:网关/反向代理(如 Nginx)无法连接到后端应用。常见原因:应用进程挂了、被 OOM killer kill 掉、内存溢出、监听端口错误或网络不通。典型现象:上游服务器无响应。 - 503 Service Unavailable:服务暂时下线(维护、过载)。应包含 Retry-After header。用户看到「服务维护中,请稍后重试」。 - 504 Gateway Timeout:网关等待后端响应超时,通常是后端应用响应很慢(数据库慢查询、大文件处理、无限循环)。超过网关的等待时间后返回此错。 - 505 HTTP Version Not Supported:服务器不支持客户端的 HTTP 版本(如客户端用 HTTP/3 但服务器只支持 HTTP/2)。现代网络中罕见。

CDN 与 5xx 的交互: - Cloudflare 等 CDN 如果检测到源站返回 5xx,会自动回源到备用源或返回缓存版本(如存在) - 502/503/504 在 CDN 层经常被转为 200(返回缓存 HTML「我们正在维护」),用户感知不到源站故障 - 如果想让 5xx 真实透传到客户端,CDN 配置中需关闭错误页缓存或设置缓存时间为 0

  1. 500:检查应用日志(/var/log/app.log),找到异常堆栈
  2. 502:检查后端应用是否运行(ps aux | grep app),查看 Nginx 错误日志(/var/log/nginx/error.log)
  3. 503:检查服务是否在维护模式,或应用是否过载(CPU、内存、连接池已满)
  4. 504:运行 curl 到应用,看响应时间。如果超过网关超时(通常 30-60s),优化慢查询或增加超时时间

监控建议: - 5xx 需紧急告警(要求秒级响应) - 502/503/504 通常来自容量不足,需扩容 - 如果某个端点频繁 502/504,是后端应用或数据库的瓶颈信号

状态码在浏览器、移动端、CDN 的处理差异

同一状态码在不同客户端(浏览器、iOS App、Android App)和中间件(CDN、Nginx)中的处理可能截然不同。

301/302 重定向处理: - 桌面浏览器(Chrome、Firefox):自动跟随重定向(用户无感知),一般跟随 5 次后停止 - iOS 原生网络库(NSURLSession):默认自动跟随 - Android okhttp:默认自动跟随 - curl 命令行:默认不跟随,需 -L 参数 - Axios / Fetch:取决于配置,通常可配置是否自动跟随

401 认证失败处理: - 浏览器:如果响应包含 WWW-Authenticate: Basic header,会弹出 HTTP Basic Auth 对话框 - iOS:通常不弹对话框,需应用自己处理(跳转登录页、刷新 token) - Android:同 iOS

429 限流处理: - 浏览器:返回 JSON 错误信息,需 JavaScript 解析并提示用户「请求过于频繁",或自动延迟重试 - 移动应用:通常按 Retry-After header 延迟重试,或累计计数后提示用户 - curl / 脚本:通常不自动重试,需手动实现重试逻辑

缓存行为差异: - 200:浏览器根据 Cache-Control / Expires header 缓存 - 301:浏览器永久缓存(重启也不失效),除非显式清缓存。这导致有时改了 301 规则但浏览器仍跳转到旧地址 - 302:浏览器通常不缓存,但可以用 Cache-Control 控制 - 404:部分浏览器短期缓存,导致临时删除页面后再恢复时仍显示 404(让人误以为故障) - 5xx:正常不缓存,但某些 CDN 配置下可能缓存 5 分钟的错误页

跨域请求的状态码: - CORS 预检请求(OPTIONS)返回的状态码决定实际请求是否发送 - 如果 OPTIONS 返回 403,浏览器不会发送后续 GET/POST 请求 - 某些状态码组合(如 401 + 无 Access-Control-Allow-Credentials)会导致跨域失败

设计 API 时避免自定义状态码的陷阱

有人想用 600、888 等自定义状态码表达特殊含义,比如 600 表示「登录过期,请重新登录」。强烈不推荐,原因如下:

标准兼容性问题: - HTTP 规范定义的状态码是 100-599 - CDN、反向代理、防火墙都认识这个范围,超出此范围的码会被拦截、转改或忽略 - 浏览器 fetch API 和 axios 等库对非标准码的处理不统一

客户端库兼容性: - 浏览器 fetch:可能将 6xx 视为网络错误 - Postman:显示 6xx 时可能出现警告或奇怪行为 - 手机 App(iOS/Android):网络库可能直接拒绝或转改状态码

可维护性差: - 非标准码需详细文档说明,新人接手代码时容易理解错 - 版本升级时容易被自动化工具(如 API 网关)重写或丢弃

最佳实践: 用标准状态码(如 401 表示认证失败)+ 响应体里的 error_code 字段来细分具体原因。 `` { "code": 401, "error": "Unauthorized", "error_code": "token_expired", "message": "Your token expired. Please login again." } ``

或者: `` { "status": 401, "errors": [ { "code": "AUTH_TOKEN_EXPIRED", "message": "Your token expired at 2026-04-29 10:30:00", "hint": "Try POST /auth/refresh-token" } ] } ``

这样既遵循 HTTP 规范,客户端库也能正确处理,响应体还能携带详细信息供客户端进一步处理。

常见问题

301 和 302 哪个对 SEO 更好?

301。搜索引擎会把旧页面的权重和关键词排名转移到新地址,SEO 完全无损。302 则保留旧地址的索引,权重不转移。所以网站永久改版、域名迁移必须用 301;临时维护用 302。

什么时候用 201 什么时候用 200?

创建新资源(POST)返回 201 Created,并在 Location header 包含新资源的 URL(如 /users/123)。查询(GET)、更新(PUT/PATCH)、删除(DELETE)返回 200 OK 或 204 No Content。这样客户端能准确识别操作类型。

403 和 404 怎么区分?

403 表示"我知道这个资源,但你没权限访问";404 表示"我不知道有这个资源"。基于安全考虑,有时也会把 403 伪装成 404 隐藏资源存在(如隐私页面)。

Retry-After 是什么?

429 或 503 响应中的 header,告诉客户端多久后重试。值可以是秒数(如 60)或 HTTP 日期(如 "Wed, 21 Oct 2026 07:28:00 GMT")。客户端应该尊重这个提示延迟重试。

502 Bad Gateway 是应用的错还是 Nginx 的错?

502 是 Nginx 返回的,说明 Nginx 无法连接到后端应用。根本原因在后端:应用进程已挂、内存溢出被 OOM killer kill 掉、监听端口错误或网络不通。需检查应用日志和进程状态。