3xx 是什么
3xx 表示客户端需要采取进一步动作才能完成请求,绝大多数是「资源换了位置」:响应里给出新的目标地址,客户端再向新地址发起请求。这个类别的坑在于方法语义:历史上部分客户端在跟随跳转时会把非读取请求改写为读取请求,请求体也会被丢掉;后出现的两个码则明确要求保持原方法与请求体。选错码会让提交类操作静默失败,因此接口场景必须先确认方法是否需要保持。
基本信息
| 范围 | 以三开头的状态码 |
|---|---|
| 含义 | 需要进一步动作,多数是重定向 |
| 关键头 | 目标地址头,除未修改情形外一般都会携带 |
| 方法影响 | 不同码对请求方法与请求体的处理不同 |
| 缓存特性 | 永久与临时两类,客户端记忆策略不同 |
典型使用场景
- 升级加密访问:明文入口统一跳转到加密地址
- 站点或域名迁移:旧地址指向新地址并更新搜索引擎收录
- 临时活动导流:活动结束后规则可以直接撤下
- 提交后跳转:避免用户刷新时重复提交表单
- 接口搬家:需要保持方法与请求体时选用保方法的码
查看真实跳转链
查看真实跳转链
curl -sIL https://example.com/old | grep -iE 'HTTP|location' # 跟随整条链,只看状态行与目标
curl -s -o /dev/null -w '%{http_code} %{redirect_url}\n' https://example.com/old # 脚本里最常用
curl -sIL https://example.com/old | wc -l # 行数过多说明跳转链很长,需要排查环选型对照
| 状态码 | 临时还是永久 | 方法是否保持 | 典型用途 |
|---|---|---|---|
| 永久且可能改写方法 | 永久 | 多数实现会改写为读取 | 站点整体迁移、升级加密访问 |
| 临时且可能改写方法 | 临时 | 同样可能被改写 | 临时跳转,兼容旧客户端 |
| 临时且强制读取 | 临时 | 强制改写为读取 | 提交之后跳到结果页 |
| 临时且保持方法 | 临时 | 保持 | 接口临时搬家 |
| 永久且保持方法 | 永久 | 保持 | 接口永久迁移 |
排查要点
- 跳转链过长或成环会让客户端反复请求直到超时,用命令行数一下链路长度
- 带请求体的接口跳转后请求体消失,先确认所用状态码是否保持方法
- 浏览器表现与命令行不一致时清一次缓存,历史规则可能被长期记住
- 跳转后地址丢参数,检查目标地址是否拼上了原始路径与查询串
永久与临时的主要差别在客户端与搜索引擎的后续行为:永久码会让客户端与引擎更新记录,临时码不会。因此临时场景使用永久码,是后期最难回滚的错误之一。
提交类请求之后的跳转如果用了可能改写方法的码,部分客户端会把请求方法改成读取并丢掉请求体,另一些会弹出重新提交确认框,用户体验与数据一致性都会受损。