HTTP 状态码中 301、302 和 307 的区别是什么?

HTTP 状态码 301、302 和 307 的区别主要在于重定向的语义和对请求方法的影响。301 表示永久重定向,通常会更改请求方法;而 302 和 307 都是临时重定向,但 307 强制保留原始请求方法。

网络协议 中等 HTTP 状态码 重定向

这三个状态码都表示重定向,核心区别在于 语义(是否永久)处理请求方法的行为

1. 语义区别

  • 301 Moved Permanently:资源已永久移至新 URL。客户端后续应使用新 URL 发起请求。
  • 302 Found (临时重定向): 资源临时移至新 URL,客户端下次仍可能请求原 URL。
  • 307 Temporary Redirect (临时重定向): 与 302 的语义相同(临时重定向),但强制保留原始请求方法。

2. 对请求方法的影响(核心差异)

301 Moved Permanently

  • 规范允许客户端将 POST 等非简单请求在重定向后改为 GET(多见于旧浏览器)。
  • 实践中现代浏览器常保留方法,但不保证全部兼容。
  • 示例场景:网站从 HTTP 永久迁移到 HTTPS(权重转移)。

302 Found

  • 重定向后,客户端可能将非 GET/HEAD 请求改为 GET(尤其是旧客户端)。
  • 隐患:原始 POST 请求若被改为 GET,丢失请求体数据。
  • 示例场景:临时维护页面跳转。

307 Temporary Redirect

  • 强制要求重定向后的请求方法必须与原始请求一致(如 POST 仍为 POST)。
  • 不存在请求方法变更的风险。
  • 示例场景:需要严格维护 RESTful 行为的临时重定向(如 POST 表单提交至临时备用地址)。

关键对比表

状态码 语义 请求方法行为 规范层级
301 永久重定向 可能被改为 GET(老旧客户端风险) HTTP/1.0+
302 临时重定向 可能被改为 GET(不安全) HTTP/1.0
307 临时重定向 强制保持原始方法(更安全) HTTP/1.1 (RFC 7231)

补充说明

  • 对于 GET 请求:301/302/307 的实际行为无差异。
  • 替代方案:
    • 永久 + 强制保持方法 → 使用 308 Permanent Redirect
    • 临时重定向 + 强制使用 GET → 使用 303 See Other(常见于 POST 后跳转)。