面试官:按 F5 刷新和在地址栏回车,浏览器的缓存策略到底有啥区别?
面试官问:"浏览器缓存策略有哪些?" 你熟练地背诵:"强缓存用 Cache-Control,协商缓存用 ETag 和 Last-Modified..." 面试官点点头,接着问:"那我在地址栏输入 URL 回车,和按 F5 刷新,这两种情况下,缓存策略生效有什么区别?" 这一问,把很多只背了 HTTP 头定义的候选人问住了。 "难道...不都是发请求吗?" 当然不是。用户行为会直接改变浏览器对缓存头的处理方式。 这篇文章就帮你把这个隐蔽的知识点挖透。 为了搞清这个问题,我们不能只看服务器发了什么头,还得看用户怎么操作。浏览器把用户行为分成了三个等级: 当你在地址栏输入 URL 回车,或者点击页面跳转链接时,浏览器会表现得"非常懒"。 它会优先看本地有没有强缓存(Cache-Control: max-age=xxx)。 结论:这是最利用缓存的方式,也是用户最常见的行为。 当你按下 F5 时,浏览器的潜台词是:"我不信本地缓存是新的,我要去服务器问问。" 这时候,浏览器会无视强缓存(Cache-Control)的有效期。哪怕 max-age 还有 100 年,它也会强制发起 HTTP 请求。 结论:F5 会跳过强缓存判断,直接进行协商缓存。 这是开发者的最爱:强制刷新。 浏览器的潜台词是:"把旧的都扔了,给我来份全新的!" 这时候,浏览器会做两件事: 这相当于告诉服务器:"别给我 304,我不要旧的,给我 200 和最新内容。" 结论:完全绕过所有缓存机制,就像第一次访问一样。 细心的同学在 Chrome Network 面板里会发现,同样是缓存,有时候显示 面试官如果追问这个,多半是想考察你对浏览器进程模型的理解。 Memory Cache(内存缓存): Disk Cache(硬盘缓存): 冷知识:浏览器通常会把小文件、频繁使用的文件扔内存;大文件、不常用的扔硬盘。但这完全由浏览器内核控制,开发者干预不了。 作为开发者,我们的终极目标是:既要缓存时间够长(省流量),又要更新够快(不发版事故)。 既然 F5 和回车的行为不可控,我们就得从文件名下手。 目前前端工程化(Webpack/Vite)的标准解法是:Content Hash。 效果: 这样,用户根本不需要关心是回车还是 F5,永远能看到最新代码,同时享受最强缓存。 简洁版(30 秒): 浏览器对缓存的处理会根据用户行为降级。 正常访问(回车/链接)最优先使用强缓存,有效就不发请求。 进阶版(1 分钟,带原理): 这本质上是浏览器在请求头里加了不同的指令。 正常访问时,浏览器查找 Disk/Memory Cache,命中强缓存则拦截请求。 当用户按 F5,浏览器会在请求头加 而 Ctrl+F5 更暴力,它会加 所以在实际项目中,我们不能依赖用户的刷新行为,而是应该用 HTML 协商缓存 + 静态资源 Hash 文件名 + 强缓存 的组合拳,来保证更新和性能的平衡。 ⚡️ 别把时间浪费在低效复习上 很多人复习抓不住重点。作为过来人,我分析了100+份大厂面试记录,将 Go/Java/AI 的核心考察点、高频题、易错点 浓缩进了一份 PDF。 不搞虚的,全是干货。 加我微信:wangzhongyang1993,备注 【面经】 免费发你,立即纠正你的复习方向,把时间用在刀刃上。三种刷新操作,三套缓存逻辑
1. "最懒"模式:地址栏回车 / 点击链接 / 前进后退
200 (from disk cache) 或 200 (from memory cache)。2. "怀疑"模式:按 F5 刷新 / 点击刷新按钮
但是!它还没彻底放弃治疗,它会带上 If-Modified-Since 或 If-None-Match 去问服务器:"这文件改了吗?"3. "暴力"模式:Ctrl + F5 (Mac: Cmd + Shift + R)
Cache-Control: no-cache 和 Pragma: no-cache。还有一个坑:Memory Cache vs Disk Cache
from memory cache,有时候显示 from disk cache。这又有啥区别?最佳实践:怎么让用户永远不按 Ctrl + F5?
app.a1b2c3d4.js。index.html 设置 Cache-Control: no-cache,每次都去服务器拿最新的 HTML。app.a1b2c3d4.js 设置 Cache-Control: max-age=31536000(一年)。index.html 引用了新的 app.e5f6g7h8.js。浏览器一看:"哟,新文件,没缓存过",立刻请求新的。面试怎么答?
F5 刷新会跳过强缓存,强制发起请求进行协商缓存(检查 ETag/Last-Modified)。
Ctrl+F5 强制刷新则是完全绕过所有缓存,请求头带 no-cache,直接向服务器要最新资源。Cache-Control: max-age=0,这就导致强缓存失效,迫使服务器进行协商缓存验证(304 判断)。Cache-Control: no-cache 和 Pragma: no-cache,不仅不读本地缓存,还暗示中间代理服务器(如 CDN)也别给旧货,必须回源拿最新的。