Appearance
浏览器缓存机制
问题
强缓存和协商缓存有什么区别?浏览器缓存的全过程是怎样的?F5 和 Ctrl+F5 有什么区别?
结论
对浏览器缓存机制的理解
浏览器缓存全过程:
- 首次请求:服务器返回 200,浏览器下载资源并缓存响应头
- 再次请求:先判断强缓存是否命中(
Cache-Control: max-age或Expires)- 命中 → 直接使用缓存,不发请求(
from cache) - 未命中 → 进入协商缓存
- 命中 → 直接使用缓存,不发请求(
- 协商缓存:发送
If-None-Match(Etag 值)和If-Modified-Since(Last-Modified 值)- 服务器比对后:资源未变更返回 304;有变更返回 200 + 新资源
很多网站资源 URL 带版本号,目的是版本更新后绕过缓存,强制浏览器重新下载。
协商缓存和强缓存的区别
强缓存
不发送请求,直接从本地读取缓存,通过以下响应头控制:
Expires(HTTP/1.0):绝对过期时间,受客户端时钟影响,已不推荐Cache-Control(HTTP/1.1,优先级高于 Expires):
| 字段值 | 含义 |
|---|---|
max-age=<秒> | 缓存有效时长(秒) |
s-maxage=<秒> | 仅对 CDN 等共享缓存生效,优先级高于 max-age |
no-cache | 不使用强缓存,但仍走协商缓存 |
no-store | 完全禁止缓存,每次都从服务器获取 |
public | 允许任何对象(含代理)缓存 |
private | 仅允许浏览器缓存,不允许代理缓存 |
注意:
no-cache≠ "不缓存",它只是要求先和服务器确认新鲜度;no-store才是完全禁止缓存。
协商缓存
强缓存未命中时,携带验证信息向服务器发请求:
| 请求头 | 响应头 | 说明 |
|---|---|---|
If-None-Match | ETag | 资源唯一标识,精确(优先级更高) |
If-Modified-Since | Last-Modified | 最后修改时间,精度到秒 |
两者同时存在时,ETag 优先。命中返回 304(不传资源体),未命中返回 200 + 新资源。
负载均衡注意:多服务器下 ETag 可能不一致(每台计算方式不同),建议此时只用 Last-Modified。
为什么需要浏览器缓存?
浏览器缓存针对前端静态资源(JS、CSS、图片等),主要目的:
- 减少服务器负担,降低带宽消耗
- 加快页面加载速度(直接从本地磁盘读取)
- 减少多余网络数据传输
点击刷新、F5、Ctrl+F5、地址栏回车的区别
| 操作 | 行为 | 结果 |
|---|---|---|
| 地址栏回车 | 正常流程,先查本地缓存是否过期 | 可能命中强缓存(from cache) |
| F5 / 点击刷新 | 本地缓存标记过期,携带 If-Modified-Since/If-None-Match | 走协商缓存,返回 304 或 200 |
| Ctrl+F5(强制刷新) | 完全忽略本地缓存,不携带条件请求头 | 服务器必须返回 200 + 完整资源 |