浏览器缓存的核心目的就是:让浏览器少发请求、少下载资源,也就等同于让页面更快、服务器压力更小。
一、整体缓存的流程
浏览器请求一个静态资源,如:CSS、JS、图片时,顺序判断:
- 先查强缓存
- 有效->直接使用本地缓存,不发请求(最快)
- 无效->进入下一步
- 再查协商缓存
- 发请求问服务器:资源变了吗?
- 没变->返回304,直接用本地缓存
- 变了->返回200+新资源
- 如果都不生效->全新请求 200+新资源
二、重点:为什么HTML 不缓存?
HTML 永远不做缓存,每次请求都必须重新请求。 原因是:
- HTML 是"入口文件",里面引入了CSS、JS、图片
- 如果HTML 被缓存了,你更新了页面,用户永远也看不懂你更新的新版页面
- 浏览器每次必须拿到最新的HTML,才知道里面的资源要不要更新
这是前端工程化的基础规则。
三、强缓存
定义:浏览器直接从本地拿资源,完全不发请求到服务器。
表现:速度极快,网络面板显示 disk cache 或 memory cache。

强缓存靠两个响应头控制
第一种:Expires(HTTP 1.0,老式、不推荐)
-
格式:绝对时间(格林威治时间)
-
例子:
yamlExpires: Wed, 31 Dec 2026 23:59:59 GMT -
意思:在这个时间点之前,都用缓存
致命缺点:依赖客户端本地时间。如果用户电脑乱了、时区错误,缓存直接永远失效或者永远不会过期。
第二种:Cache-Control(HTTP 1.1,现代标准、必用)
用相对时间,不依赖客户端时间,最稳定。
最常用:
ini
Cache-Control: max-age=86400
意思:资源缓存 86400 秒 = 1 天
其他常用值:
no-cache:跳过强缓存,直接走协商缓存no-store:完全不缓存(敏感数据用)public:所有地方都可缓存private:只有浏览器能缓存
重点问题:资源提前更新了,缓存没到期怎么办?
比如:你改了 CSS,但用户浏览器缓存还有 10 天才过期。
解决方案:文件名加哈希 / 版本号
diff
index.css?v=123
或者
index.abc123.css
原理
- HTML 每次都重新请求
- 新版 HTML 里引用的是新地址的 CSS
- 浏览器发现 URL 不一样 → 当作全新资源
- 直接放弃旧缓存,下载新文件
这就是前端打包工具(Webpack/Vite)自动给静态资源文件加哈希的原因。
四、协商缓存
定义:强缓存过期后,浏览器必须发请求询问服务器缓存资源是否还能用。
协商缓存两套机制
第一种:Last-Modified / If-Modified-Since(HTTP 1.0)
工作流程:
-
第一次请求:服务器返回最后修改时间
yamlLast-Modified: Tue, 01 Jan 2025 12:00:00 GMT -
强缓存过期后,浏览器发请求带上上次服务器返回的最后修改时间:
yamlIf-Modified-Since: Tue, 01 Jan 2025 12:00:00 GMT -
服务器对比时间:
- 一致 → 304 不是拿缓存,是允许使用缓存 304响应体几乎没有内容
- 不一致 → 200 + 新资源
缺点
- 只看时间,不看内容
- 秒级修改可能识别不到
- 服务器时间不同步会出问题
ETag / If-None-Match(HTTP 1.1,更精准)
基于文件内容生成唯一指纹(hash) ,比时间更可靠。
工作流程:
-
第一次请求:服务器返回
vbnetETag: "abc123xyz" -
再次请求(强缓存过期):
sqlIf-None-Match: "abc123xyz" -
服务器对比 hash:
- 一样 → 304
- 不一样 → 200 + 新资源
优点
- 优先级高于 Last-Modified
- 内容变才会变,时间乱改不影响
- 精准度 100%
缺点
- 服务器要计算 hash,轻微增加性能消耗
五、完整的缓存工作流
sql
浏览器请求资源
↓
检查强缓存(Cache-Control / Expires)
↓
有效?→ 直接用本地缓存(不发请求)
↓
无效?→ 发请求走协商缓存
↓
服务器对比 ETag / Last-Modified
↓
未修改 → 304,用本地缓存
↓
已修改 → 200,返回新资源
六、我们实际开发中怎么配置?
1. HTML
不设置强缓存,每次都重新请求
2. CSS / JS / 图片
-
加 hash 指纹
-
设置 长强缓存(一年)
iniCache-Control: max-age=31536000
3. 经常变的小文件
用协商缓存:
yaml
Cache-Control: no-cache
// noe-cache 跳过强缓存,直接走协商缓存
小结
强缓存不发请求最快,协商缓存发请求校验;HTML 永远不缓存,静态资源加指纹永不过期,更新全靠 HTML 牵引。