- Published on
HTTP缓存
- Authors

- Name
- Li WenKang
- https://x.com/liwenkang_space
HTTP缓存,当浏览器访问一个网站时,会把页面上的图片,css 数据下载到本地,当用户下次再访问这个页面时,浏览器就可以直接读取本地副本,避免重复加载。主要分为强缓存和协商缓存,可以用来减少网络请求,提高用户体验。
怎么做到的?
- 浏览器发出 GET 请求后,先看下是否存在强缓存?
- 如果强缓存有效,则直接读取浏览器本地缓存 200 from cache
- 如果强缓存失效,则考虑协商缓存(浏览器要携带资源身份证,向服务器验证)
- 查看上次请求响应头上是否有 ETag 字段?
- 如果有 Etag,则发起请求头上携带 If-None-Match 服务器验证资源是否可用,如果可用,则返回 304 not modified(浏览器可以使用本地缓存的文件),如果不可用,则发出正常请求
- 如果没有 Etag 字段,则查看上次请求响应头上是否有 Last-Modified 字段,如果有,则发起请求头上携带 If-Modified-Since 服务器验证资源是否可用,如果可用,则返回 304 Not Modified(浏览器可以使用本地缓存的文件),如果不可用,则发出正常请求
相关的响应头字段 Cache-Control:
- max-age:缓存存储最大时长,单位是 s
- s-max-age:缓存存储最大时长,单位是 s,仅用于代理服务器
- public:响应可以被任意对象缓存
- private:只能被私有对象缓存,不能被代理服务器缓存
- no-cache:禁用强缓存,可走协商缓存(用前必须验证)
- no-store:禁用一切缓存
Expires:服务端返回的资源过期时间,使用本地时间做判断,优先级低于 Cache-control: max-age,已经被逐渐替代。
ETag/If-None-Match:资源的唯一标识哈希值,验证精度高
Last-Modified/If-Modified-Since:资源的最后修改时间戳
浏览器本地缓存的优先级
Service Worker(可拦截请求)> memory cache(内存) > disk cache(硬盘) > Push Cache(推送缓存,http2)
解决了什么问题?
- 对用户来说:大幅提升页面加载速度,节省流量
- 对服务器来说:显著降低服务器压力,提升网站高并发能力
最佳实践是什么?
- 静态资源使用强缓存并设置较长过期时间(如1年)。同时,在构建工具(如Webpack)中为文件名添加哈希值(如main.a1b2c3.js),这样一旦资源内容变化,文件名就改变,从而强制浏览器下载新文件,既利用了缓存的速度,又能保证用户获取最新内容。
- html页面一般使用协商缓存(如Cache-Control: no-cache),确保内容更新
- f5 刷新时,浏览器会跳过强缓存,但可能进行协商缓存验证。ctrl+f5 刷新,则会去掉所有缓存,直接向服务器发送接口请求。在开发阶段,可以开启浏览器控制台的停用缓存,避免影响