图 1:本文封面,钉死的箭头与虚线箭头,就是缓存行为的差异。
先说明属性:这是一篇经典题解析,题目出自本地历史面试资料,与任何公司的当前招聘无关。「301 和 302 有什么区别」看起来是送分题——一个永久一个临时。但面试官想听的是「永久和临时」这四个字在三处产生的实际后果:浏览器缓存、搜索引擎、请求方法。
想象面试现场:「301 和 302 有什么区别?应用上各什么时候用?」
第一步,先给标准定义。
按 HTTP 语义规范(RFC 9110):301 表示目标资源被分配了新的永久地址,今后引用这个资源都应该改用新地址;302 表示资源临时位于另一个地址下,由于跳转随时可能变化,客户端今后的请求应当继续走原地址。记住最后半句——它是后面所有差异的根。
第二步,差异一:浏览器缓存行为。
301 响应是「启发式可缓存」的:即使响应里没有显式的缓存头,浏览器也可以按自己的策略把它长期缓存下来。后果很直接——用户第一次访问旧地址被 301 到新地址后,浏览器记住了这个跳转,之后连旧地址都不再请求,直接奔新地址去。302 则相反,默认不被缓存,浏览器每次都老老实实回到原地址再问一次「现在该去哪」。
这就是为什么把临时活动页错配成 301 是事故:活动结束你把服务端的跳转撤了,但缓存已经躺在千千万万用户的浏览器里,你没有任何办法通知它们失效——撤回一个被广泛缓存的 301,难度远超想象。
第三步,差异二:搜索引擎的处理。
搜索引擎把重定向当成规范地址的信号。按 Google 搜索中心的官方文档:永久重定向(301、308)会让索引系统把跳转目标当作规范地址,搜索结果里展示新地址,原地址积累的权重随之迁移过去;临时重定向(302、303、307)则不传递这个信号,搜索结果里继续保留原地址。所以网站换域名必须 301——不只是在搬家,也是在告诉搜索引擎把旧地址的全部积累过户到新地址;而临时跳转用 301 等于亲手把原地址的搜索权重送走。
第四步,差异三:请求方法能不能保持。
POST 请求收到 301 或 302,重定向后的第二次请求还是 POST 吗?规范层面 301 和 302 都没有强制要求保持方法,而大量历史客户端的实现会把它们改成 GET、丢弃请求体。如果你的场景是「接口迁移,客户端必须原样重发 POST」,301 和 302 都靠不住,正确答案是它们的严格版后代:307(临时)和 308(永久),规范明确规定这两个状态码重定向时不允许改变请求方法。
第五步,把三维差异落到决策路径。
永久换域名、旧地址永久下线:301,让浏览器缓存加速、让搜索引擎过户权重。临时活动页、灰度跳转、按条件分流:302,保留原地址的缓存自由和搜索权重。接口迁移且方法必须原样保持:307 或 308,永久还是临时按迁移性质选。决策时多问一句:「这个跳转将来要撤回吗?」要撤回就别让它进入长期缓存。
图 2:三维差异对比与选用决策路径。
可能的追问与易错点。
「303 是什么?」规范里它为「用 GET 获取另一个地址」而生,典型场景是 POST 提交完跳转到结果页。「304 也是跳转吗?」不是,304 属于协商缓存,表示资源没变、继续用本地副本,和重定向不是一族。易错点主要有三:一是只会答「永久和临时」,讲不出缓存与搜索两条实际后果链;二是给临时跳转配 301,撤回时才发现浏览器缓存不受自己控制;三是接口迁移用 301 或 302,POST 被改成 GET 后排查半天,不知道该用 307 或 308。
回到面试现场,建议的答题节奏:先给 RFC 定义并强调「302 要求继续走原地址」这个根,再按缓存、搜索引擎、方法保持三条后果链展开,最后落到决策路径。这套区分在 AI 工程里有直接代价:模型 API 的域名迁移、灰度切换都走重定向,选错状态码会让客户端永久缓存旧地址,切换失误的代价远高于想象。
你遇到过「跳转撤不掉」的事故吗?是浏览器缓存还是搜索引擎的锅?欢迎分享。