302 是什么
302 Found 表示目标资源临时位于另一个地址,客户端下次仍应访问原地址。它是历史最悠久的重定向码,也带着一个历史包袱:早期实现在收到它之后会把非读取类请求改写为读取类请求,这个行为被写进了浏览器兼容逻辑,至今仍是主流做法。因此它适合「临时跳转且不在乎方法语义」的场景,需要严格保持方法与请求体时应当改用更新的码。RFC 9110 §15.4.3 对它的定位正是临时重定向。
基本信息
| 名称 | 302 Found(RFC 9110 §15.4.3) |
|---|---|
| 作用 | 资源临时位于别处,原地址仍有效 |
| 关键头 | 目标地址头给出临时目标 |
| 方法影响 | 历史实现常把非读取请求改写为读取请求 |
| 与永久码区别 | 客户端与搜索引擎不会把原地址替换为新地址 |
典型使用场景
- 活动与推广页:临时导流到专题页,活动结束即撤下规则
- 灰度分流:按比例把部分用户临时导向新版本
- 登录后跳转:表单提交成功后跳到结果页,避免刷新重复提交
- 地域与语言跳转:按客户端特征临时导向对应版本
- 维护期导流:把入口暂时指向说明页,恢复后立即取消
观察临时跳转
观察临时跳转
curl -si http://example.com/promo | grep -iE 'HTTP|location' # 看状态行与跳转目标
curl -sIL http://example.com/promo | grep -iE 'HTTP|location' # 跟随整条跳转链
curl -s -o /dev/null -w '%{http_code} %{redirect_url}\n' http://example.com/promo # 只取状态码与目标与相邻跳转码对比
| 状态码 | 性质 | 方法是否保持 | 更适合的场景 |
|---|---|---|---|
| 临时跳转(本条目) | 临时 | 多数实现会改写为读取 | 不在乎方法语义的临时导流 |
| 永久跳转 | 永久 | 多数实现会改写为读取 | 站点迁移、升级加密访问 |
| 强制读取跳转 | 临时 | 强制改写为读取 | 提交成功后跳结果页 |
| 保持方法的临时跳转 | 临时 | 保持原方法与请求体 | 接口临时搬家 |
| 保持方法的永久跳转 | 永久 | 保持原方法与请求体 | 接口永久迁移 |
使用要点
- 提交类请求之后的跳转优先用强制读取的那个码,避免浏览器询问是否重新提交
- 需要保留请求体与方法的接口跳转用保持方法的码,别指望临时码帮你保留
- 跳转目标要带上原始路径与查询串,否则用户会丢失原本要看的页面
- 限制跳转链长度,环状跳转会让客户端反复请求直到超时
排查要点
- 先用命令行看状态行与目标地址,确认跳转是否发生在预期的那一层
- 跟随跳转链时留意状态码变化,中途出现永久码说明另有配置在起作用
- 浏览器行为异常时清一次缓存再试,历史跳转规则可能被长期记住
- 接口调用被改写为读取方法,先确认是不是这个码造成的
提交之后用临时码跳转,浏览器可能把请求方法改成读取并丢掉请求体,某些客户端还会弹出重新提交确认框。这类场景应当使用强制读取的码,语义明确且行为一致。
临时与永久的差别主要体现在客户端的缓存与搜索引擎的链接更新策略上:临时码不会替换原地址,因此是可以随时撤下、代价最小的跳转方式。
下线时的三个动作
- 先撤掉跳转规则再清理目标页,避免用户跳到已经不存在的页面
- 观察一段时间访问日志,确认原地址的请求量已经回落到正常水位
- 检查站内链接与外部引用是否仍有指向原地址,必要时改直连