旧缓存还能不能用,请求头里的缓存对话

2026年09月06日

10 次

再次访问同一个网页时,浏览器不会每次都重新下载全部内容——它手里可能有上次的缓存,代理IP链路的重复请求同样依赖这份缓存。但缓存不是拿来就用:浏览器要带着请求头去问服务器「我这份旧缓存还有效吗」,服务器给个答复,这场缓存对话才算完成。

缓存对话的巧妙在于省流量:内容没变时,服务器不必再传一遍完整内容,只回一个「没变」的信号即可。请求头里那几行缓存相关的头,就是这场对话的台词,代理IP链路中它们同样一板一眼地执行。

这篇讲请求头里的缓存机制:浏览器怎么问、服务器怎么答、以及「没变」的信号长什么样。

带着时间戳去问:If-Modified-Since

最朴素的问法是带时间:浏览器把缓存内容的最后修改时间写进 If-Modified-Since 头,服务器对比自己内容的实际修改时间——没变就回一个「未修改」的短响应,浏览器直接用缓存;变了才重新传内容。一问一答,省下大量重复传输。

带着标记去问:If-None-Match

时间戳有精度问题(一秒内的修改可能漏判),更可靠的问法是用内容标记:服务器给每份内容算一个特征值(ETag),浏览器缓存时记下它,再访时写进 If-None-Match 头。特征值相同说明内容真没变,服务器同样回「未修改」。

两种问法可以并存,也可以只用其一。现代网站普遍以特征值为主、时间为辅,两者结合能覆盖绝大多数缓存验证场景,让「刷新页面」这类操作既快又不给服务器添负担。

当服务器确认缓存有效时,不会重新传内容,而是返回一个 304 状态码的短响应——「你手里的就是最新的」。浏览器收到 304 后直接用本地缓存渲染,肉眼几乎感觉不到这次网络往返的存在,页面秒开的效果大半来自这里。

把这场对话串起来:浏览器带 If-Modified-Since 或 If-None-Match 去问,服务器用 304 或新内容作答——条件成立才回内容,这就是「条件请求」名称的由来。代理IP链路中缓存命中时同样走这套问答,理解它能解释许多「为什么第二次打开特别快」的现象。

缓存对话是条件请求:带时间戳或特征值去问「旧缓存还有效吗」,服务器用 304 说没变、用新内容说变了——省流量的关键全在这场问答里

缓存对话管「能不能复用旧内容」,还有一个头管着更基础的问题:这次访问的是哪台服务器?一台机器上可能住着好几个网站,全靠 Host 头来分——下一篇看 Host 头怎么完成分诊。

把缓存对话放到真实浏览里看:第一次访问下载全部资源,之后的访问浏览器带着条件头去问,服务器回 304,页面从缓存渲染——这就是「第二次打开明显变快」的技术解释。代理IP链路中浏览器与出口之间的这段缓存对话同样存在,只是被转发层隔了一层,观察它同样能判断请求是否真的走了代理。

缓存对话的尽头是资源的更新策略:网站改版后希望用户尽快看到新内容,会在响应头里缩短缓存期限;希望稳定复用的内容则设长缓存。理解这层博弈,你就明白为什么有时刷新页面仍看到旧内容——那不是请求头失灵,而是缓存期限还没到。

顺手记一个排障技巧:遇到「改了文件页面却不变」,多半是缓存对话判定旧缓存仍有效。强制刷新(跳过缓存的刷新)会让浏览器不带条件头重新拉取,是验证代理IP链路缓存问题最直接的手段。

缓存对话这篇的落点是刷新认知:网页快不只是服务器的功劳,浏览器与请求头里的条件协商同样关键。代理IP场景下理解缓存问答,还能解释为什么同一出口下重复任务越跑越快——缓存命中的请求根本不需要每次都走完整链路。

相关咨询请联系QQ/微信:157069302