308 是什么
308 Permanent Redirect 表示资源已永久迁移到新地址,并且明确要求客户端保持原请求方法与请求体重新发起。它和 307 的差别在于「永久」还是「临时」;和 301 的差别在于方法是否被改写。历史上 301 允许客户端把 POST 改成 GET,浏览器正是这么做的,于是一些依赖原始方法的接口在 301 后会失败。308 就是为「永久跳转但不能丢方法」这个场景补上的状态码。
基本信息
| 名称 | 308 Permanent Redirect |
|---|---|
| 作用 | 永久跳转且保持请求方法 |
| 规范 | RFC 7538 §3(308 注册)、RFC 9110 §15.4 |
| 默认缓存 | 永久重定向,浏览器与代理会长期缓存 |
| 配套头 | Location 指定目标地址 |
| 适用 | API 域名迁移、协议/主机名规范化 |
典型使用场景
- API 域名整体迁移,要求 POST/PUT 请求原样打到新地址
- 把 HTTP 请求永久引导到 HTTPS,同时不放宽写操作的方法
- 主机名规范化:www 与非 www 之间做永久跳转
- 旧接口路径永久搬到新版本路径且要保留请求体
- 排查「迁移后写请求失败」:确认是否误用了 301
API 域名永久迁移
API 域名永久迁移
# 旧域名整体永久迁移,保持方法与请求体
server {
listen 443 ssl;
server_name api.old.example.com;
return 308 https://api.example.com$request_uri;
}
# 上线前后验证:确认状态码与目标
curl -sI -X POST https://api.old.example.com/v1/orders -d '{}' \
| grep -E 'HTTP/|Location'
# 用 -L 跟随,观察最终方法是否仍为 POST
curl -s -L -o /dev/null -w '%{http_code} %{url_effective}\n' -X POST https://api.old.example.com/v1/x重定向状态码对照
| 状态码 | 是否永久 | 方法是否保持 |
|---|---|---|
| 301 | 永久 | 历史实现常被改为 GET |
| 302 | 临时 | 历史实现常被改为 GET |
| 307 | 临时 | 保持原方法与请求体 |
| 308 | 永久 | 保持原方法与请求体 |
| 303 | 临时 | 强制改为 GET(PRG 场景) |
要同时满足「永久」与「不改方法」,唯一的选择是 308;要「临时」与「不改方法」用 307。区分记忆:3 其后两位中,07/08 保方法,01/02 历史上会改方法,03 一定改成 GET。
301/308 会被浏览器长期缓存,甚至不因清缓存而立刻失效。上线前务必用 curl -I 验证跳转目标与状态码,避免把用户永久锁死在错误地址;如需回滚,往往要服务端再发一轮新的重定向才能纠偏。