一篇文章搞懂,浏览器强缓存以及协商缓存

你有没有发现,有些网页第二次打开速度特别快?这就是利用了缓存。 下面介绍一下浏览器常见的两种缓存策略。

一:强缓存

强缓存的本质是 "时间有效性验证",浏览器无需向服务器发送请求,直接根据本地缓存的过期时间判断是否可用。

假设项目中有一张图片资源:test.png。 首次请求test.png时,服务器返回Cache-Control: max-age=86400(24 小时有效期)。​ 24 小时内再次请求该图片,浏览器直接从缓存读取,网络请求瀑布图显示200OK ,不会向服务器发送请求(200仅仅表示资源加载成功,并未与服务器交互)。

强缓存类型:

1.from memory cache (资源暂存于浏览器内存)

2.from disk cache ( 资源持久化存储于本地硬盘)

关键http头部字段

Expires (单位:GMT 时间字符串)

格式:Expires: Wed, 03 Jun 2025 12:00:00 GMT​

缺点:依赖服务器时间,若客户端与服务器时钟不同步,服务器返回的过期时间就不一定是准确的,可能导致缓存提前失效或过期资源被使用​。

Cache-Control(单位:秒)

max-age=604800:7 天有效期,优先级高于 Expires​。

Cache-Control其他值:

public:允许代理服务器缓存(如 CDN)​

private:仅客户端可缓存​

no-cache:非禁止缓存,而是要求使用前必须经服务器验证(实际触发协商缓存)​

no-store:严格禁止缓存,每次请求必须从服务器获取

Cache-Control与Expires的优先级对比

Cache-Control 的优先级高于 Expires

原因:

Expires 通过 "具体时间点" 定义过期(如 Wed, 31 Dec 2025 23:59:59 GMT),但它依赖浏览器本地时间

Cache-Controlmax-age 以 "时长" 定义过期(如 max-age=86400 表示 1 秒),计算起点是 "资源首次下载完成的时间",不依赖本地时间

Cache-Control 优先级高于 Expires,核心是它解决了 Expires 依赖本地时间的缺陷。

强缓存工作流程

浏览器发起资源请求 -> 服务器返回资源,并设置缓存 -> 再次发送资源请求 ->检查是否过期 →->未过期 (不存在缓存 或 已过期 → 发起网络请求) -> 返回200(不发送网络请求)

如果资源命中值强缓存,如何更新?

改变资源唯一标识,加版本号、改变资源hash值...

二 : 协商缓存

1、触发条件与核心逻辑

当强缓存失效(如 max-age 过期),浏览器会向服务器发送请求,携带缓存标识验证资源是否更新。

2、双重验证机制

第一重:Last-Modified / If-Modified-Since

服务器响应时添加Last-Modified: Thu, 01 Jun 2025 10:00:00 GMT​

浏览器再次请求时,在请求头中携带If-Modified-Since: Thu, 01 Jun 2025 10:00:00 GMT​

服务器对比资源实际修改时间,若未变更则返回304 Not Modified,浏览器使用本地缓存

第二重:ETag / If-None-Match(优先级更高)​

服务器根据资源内容生成唯一哈希值,如ETag: "5f8e1a2b3c4d5e6f"​

浏览器请求时携带If-None-Match: "5f8e1a2b3c4d5e6f"​

服务器对比哈希值,一致则返回 304,否则返回新资源(200 OK)

3、协商缓存两种方式优先级说明

为什么ETag 的精度高于 Last-Modified?

1.某些场景下资源修改时间变更但内容未变(如修改注释)Last-Modified 会误判为更新;

2.因为Last-Modified的最小单位是秒,加入文件在一秒内改变了多次,这个时候Last-Modified的值并没有变化。

ETag 基于内容哈希,只要内容不变,即使修改时间变化也能正确识别为未更新。

协商缓存的304/200,均为服务器返回。

三、协商缓存与强缓存优先级

强缓存优先级高于协商缓存

原因:本质是为了最大化减少网络请求,提升加载性能

参考文章:

blog.csdn.net/m0_74065758...

相关推荐
云中雾丽5 小时前
flutter中 NotificationListener 详细使用指南
前端
王六岁5 小时前
# 🐍 前端开发 0 基础学 Python 入门指南: Python 元组和映射类型深入指南
前端·javascript·python
_志哥_5 小时前
多行文本超出,中间显示省略号的终极方法(适配多语言)
前端·javascript·vue.js
王六岁5 小时前
# 🐍 前端开发 0 基础学 Python 入门指南:常用的数据类型和列表
前端·javascript·python
1_2_3_5 小时前
神级JS API,谁用谁好用
前端·javascript
冬至已至5 小时前
AI 时代的自动化信息获取与整合
前端
用户6600676685395 小时前
从送花表白实例读懂 JavaScript 对象字面量与代理模式
javascript
我是日安5 小时前
从零到一打造 Vue3 响应式系统 Day 29 - readonly:数据保护实现
前端·javascript·vue.js
时代拖油瓶5 小时前
我劝你必须知道——Intl.Segmenter
前端·javascript