你真的懂HTTP 状态码吗?

100 阅读12分钟

HTTP 2xx 成功状态码全解析

📌 核心特性

所有2xx状态码均表示​​请求已被服务器成功处理​​,但不同代码对应不同语义场景 。


🔹 200 OK

​典型场景​​:

  • GET请求获取资源(如HTML页面、JSON数据)
  • POST请求提交数据后的成功响应
    ​代码示例​​:
HTTP/1.1 200 OK
Content-Type: application/json
{"data": "success"}

​关键点​​:
✅ 最通用的成功状态码
✅ 响应体通常包含请求的资源
⚠️ 与204的区别:200允许返回空内容(但不符合RFC最佳实践)


🔹 201 Created

​典型场景​​:

  • RESTful API中创建新资源(如用户注册、文件上传)
  • 需配合Location头返回新资源URI
    ​代码示例​​:
HTTP/1.1 201 Created
Location: /users/123

​关键点​​:
✅ 必须明确指示新资源的访问路径
🚫 若资源创建异步完成,应改用202 Accepted


🔹 202 Accepted

​典型场景​​:

  • 异步任务处理(如视频转码、大数据分析)
  • 需后续轮询或回调确认最终结果
    ​代码示例​​:
HTTP/1.1 202 Accepted
{
  "task_id": "abc123",
  "status_url": "/tasks/abc123"
}

​关键点​​:
🔄 仅表示请求已进入处理队列
💡 常配合Retry-After头提示检查间隔


🔹 203 Non-Authoritative Information

​典型场景​​:

  • CDN或代理服务器返回缓存的非原始数据
  • 中间节点修改了原始响应(如添加安全头)
    ​关键点​​:
    ⚠️ 生产环境罕见,多数代理直接返回200

🔹 204 No Content

​典型场景​​:

  • DELETE请求成功但无需返回内容
  • 表单提交后仅需确认成功(如点赞功能)
    ​代码示例​​:
HTTP/1.1 204 No Content

​关键点​​:
🚫 响应体必须为空
✅ 浏览器不会刷新页面或清除表单


🔹 205 Reset Content

​典型场景​​:

  • 表单提交后需要清空输入框(如问卷调查系统)
    ​关键点​​:
    🔄 与204的区别:要求客户端重置当前文档视图

🔹 206 Partial Content

​典型场景​​:

  • 断点续传(如大文件下载)
  • 视频流分片加载
    ​代码示例​​:
HTTP/1.1 206 Partial Content
Content-Range: bytes 0-999/5000

​关键点​​:
✅ 必须配合Content-Range头指定数据范围
⚠️ 若请求范围无效则返回416


🔹 207 Multi-Status (WebDAV)

​典型场景​​:

  • 批量操作返回多状态(如同时删除多个文件)
    ​响应示例​​:
HTTP/1.1 207 Multi-Status
<d:multistatus>
  <d:response><d:href>/file1.txt</d:href><d:status>200</d:status></d:response>
  <d:response><d:href>/file2.txt</d:href><d:status>404</d:status></d:response>
</d:multistatus>

​关键点​​:
🚫 非WebDAV场景极少使用


🔹 208 Already Reported (WebDAV)

​典型场景​​:

  • 避免重复报告已处理的集合成员状态
    ​关键点​​:
    📌 专用于WebDAV协议扩展

📊 2xx状态码对比速查表

状态码名称是否含响应体典型应用场景
200OK可选通用成功响应
201Created建议资源创建成功
202Accepted可选异步任务已接收
204No Content禁止无返回内容的操作成功
206Partial Content必须分块传输/断点续传
207Multi-Status必须(XML)WebDAV批量操作

一些tips

  1. ​201不会触发浏览器自动重定向​

    • 当服务器返回201 Created时,虽然响应头包含Location字段(如Location: /users/123),但浏览器​​不会自动跳转​​到该URL。这与3xx重定向有本质区别。
    • Location在201响应中的作用是​​告知客户端新资源的访问地址​​,由开发者决定后续操作(如前端手动跳转或记录该URL)。

202 Accepted的完成状态追踪

  1. ​202的工作机制​

    • 服务器返回202时,会提供​​状态查询接口​​(通过Location或响应体返回任务ID),客户端需定期轮询或通过Webhook接收完成通知。

206 Partial Content详解

  1. ​核心场景​

    • ​大文件分块下载​​:如视频播放器实现缓冲加载。
    • ​断点续传​​:客户端记录已下载的字节范围。
  2. ​通信流程示例​

    • ​请求头​​:

      GET /large-file.mp4 HTTP/1.1
      Range: bytes=0-999999  // 请求前1MB数据
      
    • ​响应头​​:

      HTTP/1.1 206 Partial Content
      Content-Range: bytes 0-999999/5000000  // 当前块范围/总大小
      Content-Length: 1000000
      Content-Type: video/mp4
      
  3. ​前后端协作​

    • ​后端​​:需解析Range头,返回对应字节流。

    • ​前端​​:使用Blob对象拼接分块:

      const chunks = [];
      fetch('/large-file.mp4', { 
        headers: { 'Range': `bytes=${downloaded}-${downloaded+chunkSize}` }
      })
      .then(res => res.blob())
      .then(blob => {
        chunks.push(blob);
        if (chunks.length * chunkSize < totalSize) {
          downloadNextChunk(); // 继续下载下一块
        } else {
          const fullFile = new Blob(chunks);
          videoElement.src = URL.createObjectURL(fullFile);
        }
      });
      

2xx代码的问题及其解决方法

虽然2xx状态码通常表示成功,但在一些场景下仍需要注意,2xx可能并不总是能表示成功,响应的内容能够达到我们预期的效果。以下是可能出现的一些潜在问题及其解决方案:

200正常返回,但出现了预期之外的内容

有时,返回200 OK状态,但交付的内容与预期不符。这在CDN及缓存领域是一个灾难的存在

201资源已经创建,但响应中缺少Location头部

201状态码表示资源已成功创建。根据HTTP规范,响应头中包括一个location头部,指示可以在哪里找到新资源。但是,有时可能会缺少此响应头。

206部分内容返回,少range头部或range不正确

206响应只响应客户端range头中标明的部分数据范围,如果缺少range或range范围不正确。在生产环境中,还会出现range的部分内容异常(多出现在range缓存场景)导致获取的部分内容异常

大量202状态返回,但请求从未成功

202状态码表示服务器已接收请求,并且正在处理,如果你一直收到202状态,但操作从未完成,这可能就需要检查处理请求的队列或进程,可能存在阻止任务完成的错误或瓶颈。

204状态码返回消息正文

204表示服务器成功处理了请求,并且响应中不包含任何内容。但是,某些服务器配置可能会在这些响应中包含消息正文。

结论

2xx状态码在http协议中,表示请求正常。但在实际生产环境中,并不是所有的2xx状态码都表示这是一个正常的响应。有些实现中,会将错误包装在2xx状态码中返回。

HTTP 重定向状态码详解:301 vs 302 vs 303

🔄 301 Moved Permanently(永久重定向)

典型场景

  • 网站域名永久迁移(http://old-domain.comhttp://new-domain.com
  • 页面永久性路径变更(/products/products-list

代码示例

// 用户访问 http://old-domain.com/about
// 服务器返回:
HTTP/1.1 301 Moved Permanently
Location: http://new-domain.com/about

核心特性​​:
✅ 浏览器会永久缓存此重定向
✅ 搜索引擎会将旧页面权重转移到新地址
🚫 不适合临时性跳转场景

🔀 302 Found(临时重定向)

​典型场景​​:

  • 网站维护期间临时跳转到维护页
  • 未登录用户访问受限页面时跳转登录页

​代码示例​​:

// 用户访问 http://example.com/dashboard (未登录)
// 服务器返回:
HTTP/1.1 302 Found
Location: http://example.com/login

​核心特性​​:
🔄 浏览器不会长期缓存此重定向
⚠️ 多数浏览器会将POST改为GET(非标准行为)
💡 适合需要反复验证的跳转场景

🔍 303 See Other(查看其他位置)

​典型场景​​:

  • 表单提交后跳转结果页
  • API操作后引导查看新资源

​代码示例​​:

// 用户POST提交到 /submit-order
// 服务器返回:
HTTP/1.1 303 See Other
Location: http://example.com/order-confirmation/12345
// 浏览器自动改用GET请求新地址

​核心特性​​:
🔄 强制将请求方法转为GET
🚫 禁止缓存跳转关系
✨ 专为POST-Redirect-GET模式设计

📊 对比总结表

状态码名称重定向性质方法处理缓存行为典型应用场景
301永久重定向永久性保持原方法可缓存域名/路径永久迁移
302临时重定向临时性保持原方法*不缓存临时维护/登录跳转
303查看其他位置临时性强制转为GET不缓存表单提交后结果页跳转

*注:302在实际实现中,大多数浏览器会将POST改为GET,但这不是HTTP标准要求

💻 代码实践分析

router.get("*", async (ctx, next) => {
  ctx.status = 302; // 临时重定向
  ctx.redirect(`${app?.options?.homePage || "/"}`); // 重定向到首页
});

选择302的原因:

  1. 作为兜底路由处理所有未匹配路径
  2. 属于临时性跳转逻辑
  3. 避免301缓存导致新路由(开发完新路由挂载上去)无法生效
  4. 确保每次访问都会重新验证路由

HTTP 4xx 客户端错误状态码全解析

📌 核心特性

所有4xx状态码均表示​​客户端请求存在错误​​,服务器无法处理。需由客户端修正请求或调整权限后重试。


🔹 400 Bad Request

​典型场景​​:

  • 请求参数缺失或格式错误(如JSON语法错误、日期格式无效)
  • URL编码错误或请求头不完整
    ​代码示例​​:
HTTP/1.1 400 Bad Request
Content-Type: application/json
{"error": "Invalid date format in 'birthday' field"}

​关键点​​:
✅ 最常见的客户端错误
🚫 需检查请求体、查询参数和请求头格式


🔹 401 Unauthorized

​典型场景​​:

  • 访问需认证的API未提供Token
  • Token过期或无效(如JWT失效)
    ​响应头要求​​:
HTTP/1.1 401 Unauthorized
WWW-Authenticate: Bearer realm="example", error="invalid_token"

​关键点​​:
⚠️ 与403的区别:401表示未认证,403表示已认证但权限不足


🔹 403 Forbidden

​典型场景​​:

  • IP被拉黑或访问受限目录
  • 用户角色无权操作资源(如普通用户访问管理员接口)
    ​代码示例​​:
HTTP/1.1 403 Forbidden
{"error": "Your IP 192.168.1.1 is blocked"}

​关键点​​:
🚫 即使提供正确凭证也可能触发(如ACL限制)


🔹 404 Not Found

​典型场景​​:

  • 请求的URL路径不存在(如拼写错误)
  • 资源已被删除且无重定向
    ​开发建议​​:
    ✅ 自定义404页面提升用户体验
    🚫 避免暴露服务器目录结构

🔹 405 Method Not Allowed

​典型场景​​:

  • 用POST请求只支持GET的静态资源
  • RESTful API中误用PUT代替PATCH
    ​响应头要求​​:
HTTP/1.1 405 Method Not Allowed
Allow: GET, HEAD

​关键点​​:
📌 必须通过Allow头声明支持的请求方法


🔹 429 Too Many Requests

​典型场景​​:

  • API调用超过速率限制(如1分钟内最多60次)
  • 爬虫请求过于频繁
    ​响应头建议​​:
HTTP/1.1 429 Too Many Requests
Retry-After: 60
X-RateLimit-Limit: 100

​关键点​​:
⏳ 需配合Retry-After提示重试时间


📊 4xx状态码速查表

状态码名称触发条件解决方案
400Bad Request请求语法错误检查参数格式和完整性
401Unauthorized未提供有效认证信息补充Token或重新登录
403Forbidden权限不足或IP受限联系管理员调整权限
404Not Found资源路径不存在核对URL或设置重定向
405Method Not Allowed请求方法不被接口支持查看Allow头改用正确方法
429Too Many Requests请求频率超限降低请求速率或等待重试

HTTP 5xx 服务器错误状态码全解析

📌 核心特性

所有5xx状态码均表示​​服务器处理请求时发生内部错误​​,需由服务器管理员或开发者修复后端问题。


🔹 500 Internal Server Error

​典型场景​​:

  • 服务器脚本崩溃(如PHP语法错误、Java NullPointerException)
  • 数据库连接失败或事务冲突
    ​代码示例​​:
HTTP/1.1 500 Internal Server Error
Content-Type: application/json
{"error": "Database connection timeout"}

​关键点​​:
✅ 最通用的服务器错误码
🔧 ​​排查步骤​​:

  1. 检查服务器错误日志(如Apache的error_log或Nginx的error.log
  2. 验证配置文件语法(如php -l检测PHP文件)
  3. 监控资源使用率(CPU/内存/磁盘)

🔹 502 Bad Gateway

​典型场景​​:

  • 反向代理(如Nginx)无法从上游服务器(如Node.js、Tomcat)获取有效响应
  • 负载均衡器后端服务宕机
    ​响应头建议​​:
HTTP/1.1 502 Bad Gateway
Retry-After: 30

​关键点​​:
🌐 ​​常见于微服务架构​
🔧 ​​解决方案​​:

  1. 检查上游服务状态(如curl -I http://upstream-service
  2. 调整代理超时设置(如Nginx的proxy_read_timeout

🔹 503 Service Unavailable

​典型场景​​:

  • 服务器过载或主动限流(如秒杀活动流量暴增)
  • 计划内维护(如数据库迁移)
    ​代码示例​​:
HTTP/1.1 503 Service Unavailable
Retry-After: 3600
Content-Type: text/html
<html><body>系统维护中,预计1小时后恢复</body></html>

​关键点​​:
⏳ ​​临时性错误​​,需配合Retry-After
🔧 ​​优化建议​​:

  1. 横向扩展服务器集群
  2. 实现熔断机制(如Hystrix)

🔹 504 Gateway Timeout

​典型场景​​:

  • 网关(如API Gateway)等待上游服务响应超时
  • 慢查询导致数据库未及时返回结果
    ​关键点​​:
    ⏱️ ​​与502的区别​​:504是等待超时,502是无效响应
    🔧 ​​调试方法​​:
  1. 分析慢查询日志(如MySQL的slow_query_log
  2. 优化SQL或增加索引

🔹 505 HTTP Version Not Supported

​典型场景​​:

  • 客户端使用HTTP/3但服务器仅支持HTTP/1.1
  • 老旧服务器未升级协议支持
    ​关键点​​:
    🔄 ​​协议协商失败​
    💡 ​​解决方案​​:升级服务器软件(如Nginx 1.25+支持HTTP/3)

📊 5xx状态码对比速查表

状态码名称错误性质典型触发场景解决方案
500Internal Server Error通用服务器错误代码异常/配置错误检查日志、修复代码逻辑
502Bad Gateway网关代理错误上游服务无响应重启服务或检查网络链路
503Service Unavailable临时不可用过载/维护/限流扩容集群或等待维护结束
504Gateway Timeout网关超时上游服务响应慢优化查询或调整超时阈值
505HTTP Version Not Supported协议不支持客户端使用高版本HTTP升级服务器或降级客户端协议