浏览器提供了 三种不同的刷新方式,它们对缓存的处理方式不同,导致缓存可能失效:
1. 正常操作(直接打开页面/点击链接)
强制缓存有效,协商缓存有效
原理
- 浏览器首先检查本地缓存(强缓存),如果 Cache-Control 允许缓存(max-age 未过期),则直接从缓存读取数据,不发起请求。
- 如果强缓存过期,进入 协商缓存(If-Modified-Since / If-None-Match),服务器决定是否返回 304 Not Modified 还是新的资源。
- 最终情况
a.如果资源未过期(强缓存生效) → 直接使用本地缓存。
b.如果资源过期但未更新(协商缓存生效) → 服务器返回 304,继续使用本地缓存。
c.如果资源更新 → 服务器返回 200,重新获取资源。
2. 手动刷新(F5 / 右键刷新 / 浏览器刷新按钮)
强制缓存失效,协商缓存有效
原理
- 浏览器跳过强缓存,不管 Cache-Control 设定了多长的 max-age,都会重新向服务器发起请求。
- 但仍然使用协商缓存,即浏览器会带上 If-None-Match 和 If-Modified-Since,询问服务器资源是否有更新:
a.如果资源未修改 → 服务器返回 304 Not Modified,继续使用缓存。
b.如果资源已修改 → 服务器返回 200,重新获取资源。
- 最终情况
- 资源如果没变,仍然可以使用本地缓存(协商缓存)。
- 但强缓存已失效,必须与服务器确认资源是否最新。
3. 强制刷新(Ctrl + F5 / Cmd + Shift + R)
强制缓存失效,协商缓存失效
原理
- 浏览器完全跳过缓存(无论是强缓存还是协商缓存)。
- 直接向服务器重新请求所有资源,不携带 If-None-Match 和 If-Modified-Since 头。
- 服务器无论如何都返回 **200 OK**,并返回最新资源。
- 最终情况
a.所有资源都被重新下载,保证最新版本。
总结
刷新方式 | 强缓存 (Cache-Control) | 协商缓存 (ETag, Last-Modified) | 是否请求服务器 |
正常操作(点击链接 / 直接打开页面) | ✅ 有效 | ✅ 有效 | ❌ 仅强缓存生效时不请求 |
手动刷新(F5 / 右键刷新) | ❌ 失效 | ✅ 有效 | ✅ 请求服务器,可能返回 304 |
强制刷新(Ctrl + F5 / Cmd + Shift + R) | ❌ 失效 | ❌ 失效 | ✅ 请求服务器,直接返回 200 |
面试官可能的追问
面试官:手动刷新和强制刷新为什么都会让强缓存失效?回答:手动刷新(F5)会让 Cache-Control 失效,但仍然使用 ETag / Last-Modified 进行协商缓存。而强制刷新(Ctrl+F5)会让浏览器不带缓存标头,完全重新请求所有资源。
面试官:如何让浏览器强制缓存但能及时更新?回答:
- **设置 Cache-Control: max-age=31536000, immutable**,让静态资源缓存 1 年。
- 给资源文件名加上版本号或 Hash(app.abc123.js),每次更新资源时修改文件名,确保新版本能被正确加载。
面试官:如果用户访问了旧的缓存文件,如何让他强制刷新?回答:
- 更改资源 URL(文件名带版本号)。
- 后端设置 Cache-Control: no-cache,强制浏览器每次请求服务器验证。
- 使用 Service Worker 监听新版本,通知用户刷新。
最佳面试回答
“浏览器缓存主要分为 强缓存(Cache-Control)和 协商缓存(ETag / Last-Modified)。不同的刷新方式会影响缓存策略:
- 正常操作(点击链接、访问页面) → 强缓存生效,减少请求。
- 手动刷新(F5) → 强缓存失效,但协商缓存仍然生效。
- 强制刷新(Ctrl + F5) → 彻底跳过缓存,重新请求所有资源。
在前端优化中,我们通常结合 长期缓存 + 版本号更新策略,让浏览器高效使用缓存,同时确保资源更新。”
这样回答不仅清晰地阐述了缓存机制,还能体现出你的实战经验,面试官一定会认可你的专业性!