GUIDE 02
301、302、303、307、308 如何选择
状态码表达的不只是“跳到哪里”,还包括迁移是否永久,以及后续请求应不应该保留原方法和请求体。
| 状态 | 含义 | 方法处理 | 典型场景 |
|---|---|---|---|
| 301 | 永久移动 | 历史客户端可能改为 GET | 页面、域名永久迁移 |
| 302 | 临时移动 | 历史客户端可能改为 GET | 短期维护、临时分流 |
| 303 | 查看其他资源 | 明确改为 GET | POST 后展示结果页 |
| 307 | 临时重定向 | 严格保留方法和请求体 | 临时 API 路由 |
| 308 | 永久重定向 | 严格保留方法和请求体 | 永久 API 或协议迁移 |
301:面向长期迁移的传统选择
当旧 URL 已永久被新 URL 取代,并且未来不计划恢复时使用 301。搜索引擎通常会逐步把旧地址信号合并到新地址,但这并不等于排名、抓取频率或收录会立即无损迁移。目标内容对应关系、站内链接、canonical 和 sitemap 同样重要。
对普通 GET 页面,301 仍是兼容性最广的选择。对 POST、PUT 等非 GET 请求,历史实现可能把后续请求改成 GET,因此 API 迁移更适合 308。
302:确实临时时才使用
302 表示当前资源暂时位于其他地址,原 URL 仍有继续使用的意义。维护窗口、短期活动、灰度分流可以使用 302。若一个迁移数月后仍不会撤销,却长期保持 302,会让缓存、搜索引擎和维护人员难以判断你的真实意图。
303:提交后跳到结果页
303 明确要求客户端使用 GET 请求 Location,典型模式是“POST/Redirect/GET”:表单成功提交后返回 303,浏览器再 GET 结果页。这样刷新结果页不会重复提交原始表单。它不是普通 SEO 页面迁移的常用状态。
307 与 308:保留请求语义
307 是临时的,308 是永久的;两者都要求客户端保留原请求方法和请求体。如果 API 的 POST 请求被 307 到新地址,后续仍应是 POST。这个特性更精确,也意味着目标端必须能够安全处理同样的方法和数据。
注意:不要在不了解请求体重放风险时把支付、创建订单等非幂等请求随意重定向。客户端重试和代理行为需要单独设计。
选择流程
- 先判断变化是否真的永久。能明确撤销时间或依赖条件,通常属于临时。
- 判断是否只处理 GET/HEAD 页面。涉及其他方法时,优先考虑 307/308 的语义。
- 确认目标能接收相同请求,且不会因重放造成重复副作用。
- 测试缓存和 CDN 行为,尤其是永久状态码。
- 记录规则所有者、上线日期和撤销条件。
不要用 Meta Refresh 替代 HTTP 重定向
Meta Refresh 需要先下载 HTML 才能执行,增加延迟,也可能被脚本、无头客户端和搜索引擎以不同方式处理。能在 HTTP 层完成的迁移,应优先返回正确的 3xx 和 Location。JavaScript 跳转同样不适合承担站点规范化的基础职责。