HTTP 状态码中 301、302 和 307 的区别是什么?
HTTP 状态码 301、302 和 307 的区别主要在于重定向的语义和对请求方法的影响。301 表示永久重定向,通常会更改请求方法;而 302 和 307 都是临时重定向,但 307 强制保留原始请求方法。
这三个状态码都表示重定向,核心区别在于 语义(是否永久) 和 处理请求方法的行为:
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 后跳转)。