网页一直显示旧内容?F5和Ctrl+F5不是一回事,四层缓存我挨个清了个遍

上个月家里路由器被黑那回(排查全过程我写过一篇完整的),DNS被改成野服务器,网页右下角弹广告。我把路由器固件升了、密码改了、DNS填回223.5.5.5,电脑当场干净。媳妇手机还弹。同一个WiFi,一台好一台坏,我对着她的手机折腾到晚上十点才反应过来:她看网页从来不在浏览器里看,全是微信聊天框里点开的——微信那个内置浏览器,把旧的DNS记录和旧的网页整个存在了自己的仓库里,路由器修得再干净,它也不问。
一、先分清:网页「旧」,旧在哪一层
很多人把「网页显示旧内容」当成一件事,实际上从你敲完网址到页面弹出来,中间有四层东西都可能「旧」,清法各不相同。先把这张表看明白,后面全好办:
| 哪一层 | 存的是什么 | 旧了的表现 | 怎么清 |
| 浏览器DNS缓存 | 域名指到哪个IP | 别人都能开,就你开着旧页面 | 强刷或清浏览器数据 |
| 系统DNS缓存 | 同上,整台电脑共用一份 | 换完DNS命令行里还返回老IP | ipconfig /flushdns |
| 网页文件缓存 | 图片、样式、脚本存在本地 | 页面内容或排版是老的 | Ctrl+F5或清浏览数据 |
| 跳转记忆 | 301永久跳转和https记忆 | 死活跳老域名、死活跳https | 清「网站数据」 |
狂按F5只碰得动第三层的一部分,剩下三层它一点办法没有。这就是为什么有人刷新了几十下、重启了手机,页面还是旧的——按错层了。
二、浏览器为什么存旧网页:不是偷懒,是省流量
我拿自己博客做过一回实验。首页全部加载完是1.6MB、一共89个请求,第一次冷打开要4秒多;把标签页关掉重开,0.6秒就出来了。开F12看Network面板,89个请求里80多个的Size一栏写着from disk cache——浏览器压根没去服务器拿,直接用了硬盘里上回存的。
这套机制分两档。第一档叫强缓存,可以理解成保质期:服务器发文件的时候顺手带一句「这批图片三个月内不用再来要」(响应头里的Cache-Control和max-age),浏览器就放心存着,保质期内你再访问,它连问都不问服务器。第二档叫协商缓存,过了保质期,浏览器拿着手里版本的编号去问一句「我这版还有效吗」,服务器比对一下没变,就只回一个304状态码(意思是「没改过」),浏览器继续用本地的;真变了才回200,带上新文件。
这套设计对日常是好事——省流量、开得快。麻烦出在「服务器那头改了,你这头还在保质期里」。网站更新了文章、路由器换完DNS、劫持被修掉,本地这份缓存都不知道。
三、电脑上三招:F5、Ctrl+F5、无痕窗口
这三个我按顺手程度排。
F5是普通刷新。它只对主文档认真,请求会带上「必须验证」的标记,但图片、样式这些配角很可能直接继续用缓存。所以「按了F5还是旧的」太正常了,它本来就没答应你全部重来。
Ctrl+F5才是真强刷(Mac上是Cmd+Shift+R)。它在每个请求头里塞上Cache-Control: no-cache,所有文件全部重新向服务器要,本地缓存一律不理。F12面板里能看到一排整整齐齐的200,没有一个from disk cache——这才叫干净。
无痕窗口是照妖镜。无痕窗口从零开始、不带任何旧缓存,拿它当「标准答案」用:同一个网址,无痕窗口里是新的、正常窗口里是旧的,坐实了是缓存问题,清就完了;无痕窗口里也是旧的,那不关你手机的事,要么网站自己没更新,要么是DNS层面被指去了老地方,往第一二层查。
还有个隐藏档:开发者工具开着的时候,右键点浏览器的刷新按钮,菜单里会多出一项「清空缓存并硬性重新加载」——先清空再请求,比Ctrl+F5还彻底。我改自己博客模板的时候就靠它,改一眼刷一眼。
四、手机上最麻烦的是微信
媳妇那台手机的答案在这。微信内置的浏览器(安卓上老版本叫X5内核,新的叫XWeb)有自己独立的缓存仓库,跟系统浏览器完全不通气,你在手机设置里清一百遍浏览器数据,微信里那些网页照旧。
正路是进微信里清:微信「我」→「设置」→「通用」→「存储空间」,等它把缓存大小算出来(微信存得多的话这一步要等十几秒),点「清理缓存」。媳妇那台清出1.9G,清完再点开同样的链接,广告没了。要说代价:这个清理只动缓存,聊天记录和文件不碰,但内嵌网页的登录状态会一起掉,下次在微信里打开要登录的页面得重新登一遍。
安卓还有个老办法,在微信里给自己发送debugx5.qq.com这个链接,点开能进内核调试页,里面可以单独清网页缓存。新版微信不一定还留着这个入口,有就用,没有就走存储空间那条路,别恋战。
手机浏览器这头:iOS的Safari在「设置」→「Safari浏览器」→ 拉到底「清除历史记录与网站数据」;只想清缓存不清历史记录的话,走「设置」→「App」→「Safari浏览器」→「高级」→「网站数据」→「移除所有网站数据」,这条我更推荐,历史记录留着翻旧页用。安卓Chrome是地址栏右边三个点 →「历史记录」→「清除浏览数据」,时间范围选「过去1小时」就够了,别手一抖选「所有时间」,把存了几个月的登录状态全送走。
五、301和https的长记性:最冤的两层
有两层「旧」按F5是完全没用的,因为它们不是文件,是浏览器记的规矩。
301是永久跳转。服务器说「这个地址永久搬走了」,浏览器就把这条搬家记录存在本地,之后你输老地址,浏览器直接照着本地记录跳,根本不再问服务器。坑在哪?网站运营者手滑把301配错了、再改回来,服务器那头早就是对的,可老访客的手机里还存着错的那条,一直跳错地方。我以前把博客一个栏目换了目录,忘了先撤301,折腾一下午发现怎么改新地址都跳回老目录——错的那条就记在我自己浏览器里。清法:清掉「网站数据」或者清除浏览数据里勾上「缓存的图片和文件」。
HSTS是https记忆。你访问过的网站可以通过一个响应头告诉浏览器「以后一律用https连我」,浏览器从此焊死,你手输http://它也给你掰回https://。这个机制是防劫持的好东西,我写http和https区别那篇提过它,登录页被强制跳https踩坑的排查也单独写过一篇。但代价是:哪天这个站的https证书坏了,浏览器死活不让你用http打开,报的还是吓人的错误页——其实是记忆在替你做主。想分辨「真打不开」还是「记忆作祟」,无痕窗口开一下,无痕不吃HSTS的存量记忆。
六、收尾:按症状查,四步顺序收走
| 症状 | 先试 | 不行再 |
| 页面内容、排版是旧的 | Ctrl+F5强刷 | 清浏览器「缓存的图片和文件」 |
| 别人能开就我打不开/开旧的 | 无痕窗口对照 | 查DNS层:命令行ipconfig /displaydns看一眼,再flushdns |
| 死活跳老域名、错误页面 | 清「网站数据」 | 无痕验证,无痕也跳就是服务端的事 |
| 微信里网页旧 | 微信存储空间清缓存 | 复制链接到系统浏览器里开 |
顺序口诀就一句:先对照(无痕)、再强刷(Ctrl+F5)、后清缓存、末了才动DNS。DNS那层是另一个世界,我在改DNS不生效那篇里写过三查,flushdns管的是系统层;浏览器自己那份DNS缓存它管不着,两层要分开清。真要动到路由器那头,改法我分品牌写过:小米的在这,光猫侧的在这。想彻底搞明白域名解析这趟流程的,翻我拿nslookup跑DNS解析那篇,三层小本本的结构和这篇正好接上。
回到媳妇那台手机:微信清完缓存,当晚就干净了。过了两天她又来找我,说公众号里一个商城页面付不了款——我这回学乖了,先让她复制链接丢到系统浏览器里打开,好的。微信内核的事,别跟它讲道理,换条路最快。

发表评论