307 与 302 的区别
307 Temporary Redirect 与 302 同属临时重定向,区别在于对请求方法的要求:307 明确禁止客户端把 POST 改成 GET,必须用原方法和原请求体重新发往新地址。历史实现里不少客户端会把 302 的 POST 降级成 GET,这也催生了 303 与 307 的出现——需要方法保持就用 307,需要明确改成 GET 就用 303。
基本信息
| 名称 | 307 Temporary Redirect |
|---|---|
| 语义 | 临时跳转且保持请求方法与请求体 |
| 规范 | RFC 9110 §15.4.8 |
| 对照 | 301 与 308 为永久跳转、302 可能改写方法、303 强制改为 GET |
| 缓存 | 默认不缓存,除非显式给出缓存指令 |
重定向状态码对照
| 状态码 | 临时或永久 | 方法处理 |
|---|---|---|
| 301 | 永久 | 历史上可能被改写为 GET |
| 302 | 临时 | 历史上可能被改写为 GET |
| 303 | 临时 | 强制改为 GET |
| 307 | 临时 | 必须保持原方法与请求体 |
| 308 | 永久 | 必须保持原方法与请求体 |
API 网关临时切换节点
API 网关临时切换节点
curl -si -X POST https://api.example.com/upload -d @file.bin
# HTTP/1.1 307 Temporary Redirect
# Location: https://api-b.example.com/upload
# 客户端应带原 POST 方法与请求体重新发往新地址(body 会被重放)
# 若客户端把方法降级成 GET,服务端会收到一个没有体的请求,表现为上传参数为空典型使用场景
- 网关临时把写请求切到备用节点,同时保持 POST 语义不变
- 灰度或运维切换期间保持方法与请求体,避免出现「参数丢失」类事故
- 对象存储返回临时跳转地址,客户端按原方法重放上传
- 排查「上传偶发为空」:确认链路中间的重定向是否把方法改写成了 GET
307 要求客户端把请求体重新发往新地址,大文件会带来双份上传流量;容量规划与带宽预算要把这段重复传输算进去,否则容易出现「文件越大越慢且带宽翻倍」的现象。
307 与 308 都不限制客户端重试,但业务侧要注意幂等性:同一个非幂等请求被重放两次(如支付下单),需要靠幂等键去重,这是重定向语义之外的应用责任。