在HTTP缓存策略中,强缓存和协商缓存是两种常用的机制,用于减少数据传输和提高网页加载速度。它们通过在客户端和服务器之间建立缓存来避免不必要的网络请求,从而优化性能并提高用户体验。本文将详细介绍这两种缓存策略的原理、优势和适用场景,并提供一些最佳实践建议。

✅强缓存(Strong Cache / Local Cache)

强缓存是一种预先设定缓存时间的机制,允许浏览器在设定的时间内直接使用本地缓存数据,而无需向服务器发送请求。强缓存通过在HTTP响应头中设置Expires和Cache-Control字段来实现。

核心理念

"不用问服务器,直接用自己的!" 浏览器在发起请求前,先检查本地是否有缓存副本,并判断该副本是否还在有效期内。如果有效,则完全不发送任何请求到服务器,直接从本地缓存中读取资源。这是速度最快、对服务器压力最小的缓存方式。

实现方式

主要通过 HTTP 响应头设置有效期,即HTTP Header 中的 Expires 或 Cache-Control

Expires字段

指定资源的过期时间,是一个绝对时间点。例如:Expires: Wed, 21 Oct 2023 07:28:00 GMT。

该字段指定了缓存数据的过期时间,浏览器在过期时间之前不会向服务器发送请求。

需要注意的是,Expires字段基于服务器的时间,因此如果服务器时间不准确,可能会导致缓存失效。

Cache-Control字段

该字段提供了更强大和灵活的缓存控制功能。

通过设置不同的指令,如max-age、no-cache、no-store等,可以控制缓存的行为。

其中,max-age指令指定了缓存数据的最大有效期,no-cache指令表示需要向服务器进行验证,而no-store指令则禁止浏览器存储任何数据。

常用的属性有 max-age,以秒为单位指定资源的有效期。例如:Cache-Control: max-age=31536000 表示资源在 31536000 秒内(1 年)有效。

强缓存的优势在于它能够显著减少不必要的网络请求,提高网页加载速度。

然而,它也存在一些局限性。例如,当缓存数据过期时,浏览器仍然需要向服务器发送请求进行验证。此外,对于动态内容或需要根据用户个性化设置的内容,强缓存可能不是最佳选择。

强缓存案例

📌浏览器发起请求

1.用户访问页面需要加载 logo.png

2.示例请求: GET /static/logo.png

📌检查缓存头

// 可能的响应头示例
HTTP/1.1 200 OK
Cache-Control: max-age=31536000  // 1年有效期
Expires: Wed, 21 Oct 2026 07:28:00 GMT
Content-Type: image/png

📌缓存验证决策树

📌强缓存命中场景

✅ 内存缓存: Status: 200 (from memory cache)
(小文件/高频访问资源)

✅ 磁盘缓存: Status: 200 (from disk cache)
(大文件/低频访问资源)

📌强缓存未命中场景

❌ 首次访问: 无缓存记录

❌ 缓存过期: max-age/Expires超时

❌ 用户强制刷新: Ctrl+F5

📌关键特征流程

1.时间轴对比
资源获取时间点: [2025-06-14 10:00:00]
max-age: 31536000秒 (1年)
────●───────────────────────────────●────> 时间线获取时间                        过期时间2025-06-14 10:00:00            2026-06-14 10:00:00
2.缓存位置区分
┌──────────────────────────┐
│       Memory Cache       │
│  (高频访问的小资源)        │
│  ● logo.png (10KB)       │
│  ● user-avatar.png (5KB) │
└──────────┬───────────────┘│
┌──────────▼───────────────┐
│        Disk Cache        │
│  (低频访问的大资源)        │
│  ● banner.jpg (2MB)      │
│  ● video-intro.mp4 (8MB) │
└──────────────────────────┘
3.HTTP头对比表
类型示例值优先级
Cache-Controlmax-age=31536000, public
ExpiresWed, 21 Oct 2026 07:28:00 GMT
4.强缓存完整流程图

✅协商缓存

协商缓存是一种基于请求和响应的缓存机制,允许浏览器和服务器根据特定的规则和条件来确定是否使用缓存数据。协商缓存通过在HTTP请求和响应头中设置Etag和If-None-Match字段来实现。

协商缓存是在缓存过期后,浏览器发送请求到服务器,由服务器根据请求头中的特定字段判断资源是否更新。如果资源未更新,服务器返回 304 Not Modified,浏览器继续使用本地缓存

协商缓存核心理念

 "问问服务器,我本地的这个副本还能不能用?" 当强缓存失效(过期)或者响应头明确要求使用协商缓存(如 Cache-Control: no-cache)时,浏览器会向服务器发送一个请求。但这个请求不是直接要求完整资源,而是携带一些“验证令牌”,询问服务器:我本地这个版本还新鲜吗? 如果服务器判断资源没变,就返回一个轻量级的 304 Not Modified 响应,告诉浏览器“直接用你本地的吧!”;如果资源变了,服务器就返回完整的 200 OK 响应和新资源。

💡协商缓存目标

在强缓存失效或不可用时,避免传输未修改资源的完整内容,只传输必要的头信息,节省带宽

💡协商缓存实现方式

HTTP Header 中的 Last-Modified / If-Modified-Since 和 ETag / If-None-Match。
Last-Modified / If-Modified-Since:

Last-Modified

服务器在响应中返回资源的最后修改时间。


If-Modified-Since

浏览器在请求中携带上次的 Last-Modified 值,服务器根据此值判断资源是否更新。

Etag字段

该字段是一个由服务器生成的唯一标识符,用于标识缓存数据的版本。当客户端向服务器发送请求时,它会将Etag值包含在If-None-Match字段中。如果服务器判断客户端的Etag值与当前数据版本不一致,则会返回新的数据;否则,服务器会返回一个304 Not Modified状态码,表示客户端可以使用本地缓存数据。

If-None-Match字段

该字段用于在客户端向服务器发送请求时传递Etag值。通过比较客户端和服务器的Etag值,服务器可以决定是否返回新的数据或让客户端使用本地缓存数据。

协商缓存的优势在于它能够更好地处理动态内容和用户个性化设置。

当数据发生更改时,服务器会返回新的Etag值,从而更新客户端的缓存数据。此外,协商缓存还支持多级缓存代理的使用,提高了缓存的效率和可靠性。

如果资源未修改,服务器返回 304,浏览器使用缓存,如果资源已修改,服务器返回 200 和新的资源内容

协商缓存案例

📌验证流程

📌HTTP头交互示例

首次请求响应头:
HTTP/1.1 200 OK
ETag: "abc123"
Last-Modified: Wed, 21 Oct 2025 07:28:00 GMT
Cache-Control: no-cache
Content-Type: application/json
条件请求头:
GET /api/data.json HTTP/1.1
If-None-Match: "abc123"
If-Modified-Since: Wed, 21 Oct 2025 07:28:00 GMT

📌状态码说明

┌────────────┬─────────────────────────────────────┐
│  状态码    │ 含义                                │
├────────────┼─────────────────────────────────────┤
│   304     │ 资源未修改,节省带宽                 │
│            │ 响应头会更新缓存有效期               │
├────────────┼─────────────────────────────────────┤
│   200     │ 资源已修改,返回完整数据              │
│            │ 更新本地缓存                        │
└────────────┴─────────────────────────────────────┘

 📌时间线示意图

客户端缓存时间轴:
[获取资源]           [条件请求]2025-10-21 10:00    2025-10-22 10:00│                   │└─────未修改────────┘服务器修改时间轴:
[最后修改时间]        [当前时间]2025-10-21 07:28    2025-10-22 07:28│                   │└─────未触发更新─────┘

📌协商缓存完整流程图

协商缓存性能提示

+-----------------------------+
| 协商缓存优化点:              |
| 1. 304响应仅传输约300B的头信息 |
| 2. 200响应平均节省60%带宽      |
|    (相比无缓存重复传输完整数据) |
+-----------------------------+

✅强缓存和协商缓存关键点对比

关键区别总结

特性强缓存 (Strong Cache)协商缓存 (Conditional Cache)
是否发请求不发请求 (直接本地读取)发请求 (带验证头询问服务器)
目标完全避免网络交互避免传输未修改资源的完整内容 (节省带宽)
关键头Cache-Control (max-agepublicprivateimmutable), ExpiresLast-Modified / If-Modified-SinceETag / If-None-Match
状态码200 (from disk/memory cache)304 (Not Modified) 或 200 (OK)
速度最快 (零延迟)较快 (有验证请求的延迟,但比传输完整资源快)
服务器压力最小 (无请求)较低 (处理轻量级验证请求)
更新及时性较低 (过期前用户看不到更新)较高 (每次过期都会检查服务器)
典型配置Cache-Control: max-age=31536000, immutable (带哈希的静态资源)Cache-Control: no-cache 或 Cache-Control: max-age=0 + ETag (需要及时更新的资源)

HTTP 状态码可视化

+-------------------+---------------------+
|     状态码        |      含义           |
+-------------------+---------------------+
| 200 (from cache) | 强缓存命中           |
|      304         | 协商缓存未修改       |
|      200         | 全新资源            |
+-------------------+---------------------+

缓存头作用域

┌───────────────────────────────────────┐
│          Cache-Control 指令           │
├──────────────┬────────────────────────┤
│   public     │ 允许所有缓存           │
│   private    │ 仅浏览器缓存           │
│   max-age=3600 │ 缓存1小时            │
│   immutable  │ 永久强缓存             │
│   no-cache   │ 强制协商缓存           │
│   no-store   │ 禁用所有缓存           │
└──────────────┴────────────────────────┘

✅缓存位置 (Disk Cache vs. Memory Cache)

当浏览器决定使用缓存(无论是强缓存还是协商缓存后的 304)时,资源可能来自:

  • Memory Cache (内存缓存):

    • 存储位置: RAM。

    • 特点: 读取极快,但容量小,生命周期短(随 Tab 关闭或进程结束而释放)。

    • 常见资源: 当前导航中已下载的子资源(脚本、样式、图片),特别是较小的、高频访问的资源。开发者工具中显示 (from memory cache)

  • Disk Cache (磁盘缓存):

    • 存储位置: 硬盘。

    • 特点: 读取相对慢(但仍远快于网络),容量大,生命周期长(可跨会话、跨重启)。

    • 常见资源: 大文件(如较大的 JS/CSS、图片、字体)、访问频率较低的文件、设置了长时间 max-age 或 immutable 的文件。开发者工具中显示 (from disk cache) 或 (from ServiceWorker)(如果通过 Service Worker 缓存)。

浏览器根据自身算法(资源大小、使用频率、可用内存等)决定将资源放入 Memory Cache(内存缓存) 还是 Disk Cache(磁盘缓存)。开发者通常无法直接控制。

在实际应用中,强缓存和协商缓存可以结合使用,以充分利用它们的优点。例如,对于静态资源(如图片、CSS和JavaScript文件),可以使用强缓存来减少不必要的网络请求;而对于动态内容和用户个性化设置,可以使用协商缓存来确保数据的实时性和准确性。

✅实践建议与注意事项

对静态资源使用强缓存 + 内容哈希: 这是性能优化的黄金法则。给文件名添加内容哈希(如 app.[contenthash:8].js)。设置很长的 max-age (如一年 max-age=31536000) 或 immutable。文件内容变,哈希变,URL变,浏览器自动请求新文件。

对 HTML 文件谨慎使用强缓存: HTML 是入口文件,通常需要及时更新。可以:

设置较短的 max-age (如几分钟 max-age=300) 或 no-cache + ETag。这样用户刷新能看到更新。

或者完全 no-store (但牺牲了性能)。

或者利用服务器配置(如 nginx 的 expires -1)设置 Cache-Control: no-cache

优先使用 Cache-Control 而非 Expires max-age 更精确可靠。

优先使用 ETag 而非 Last-Modified ETag 更精确,能避免时间戳问题。

理解 no-cache 和 no-store 的区别: no-cache 不是不缓存,是强制验证。no-store 才是真正的不缓存。

利用 Vary 头处理内容协商: 如果资源内容会根据请求头(如 Accept-LanguageUser-Agent) 变化,使用 Vary 头告知缓存系统哪些请求头会影响响应内容。例如 Vary: User-Agent

调试工具: 浏览器开发者工具 (F12) 的 Network 面板是调试缓存行为的关键:

查看请求和响应的完整 Headers (Cache-ControlETagLast-ModifiedExpires)。

观察 Status 列 (200304200 (from cache))。

观察 Size 列 ((from disk cache)(from memory cache), 实际字节数)。

勾选 Disable cache 选项可完全禁用缓存(用于开发调试)。

服务器配置: 缓存策略主要在服务器端配置(Web 服务器如 Nginx/Apache,或应用框架中间件)。

Nginx 配置静态资源强缓存示例:

location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$ {expires 1y; # 设置 Expires 头 (一年)add_header Cache-Control "public, max-age=31536000, immutable"; # 更优的 Cache-Control
}

Nginx 配置 HTML 协商缓存示例:

location / {# ... other config ...add_header Cache-Control "no-cache"; # 或 max-age=0etag on; # 启用 ETag 生成# 通常 also_last_modified on; 是默认的,但明确 ETag 优先
}

用户行为影响:

  • 正常导航/跳转: 遵循缓存策略。

  • 地址栏回车: 浏览器通常会发送请求,可能触发协商缓存 (If-None-Match/If-Modified-Since),但可能使用较新的本地缓存副本(如果可用且未过期)。

  • 刷新 (F5 / Ctrl+R / 浏览器刷新按钮): 浏览器通常会发送请求,且可能在请求头中添加 Cache-Control: max-age=0 或 Pragma: no-cache跳过强缓存检查,直接触发协商缓存

  • 强制刷新 (Ctrl+F5 / Cmd+Shift+R / 清除缓存并硬性重新加载): 浏览器在请求头中添加 Cache-Control: no-cache 和 Pragma: no-cache跳过所有缓存(强缓存和协商缓存),强制从服务器下载完整新资源。同时清除当前页面的本地缓存(仅对该次请求有效)

使用顺序

  1. 浏览器首先查看资源是否命中强缓存,如果命中则直接使用缓存,不发送请求。
  2. 如果强缓存未命中,浏览器会发送请求到服务器,进入协商缓存流程。
  3. 服务器根据请求头判断资源是否更新,返回 304 或新的资源。
  4. 浏览器根据服务器响应,决定使用缓存或更新缓存。

✅对比总结

通过理解强缓存和协商缓存的原理、优势和适用场景,我们可以更好地优化网页性能和改善用户体验。在实际应用中,根据不同的需求选择合适的缓存策略是非常重要的。

对于静态资源,强缓存是一种有效的优化手段;

而对于动态内容和用户个性化设置,协商缓存则提供了更好的解决方案。

同时,结合使用这两种缓存策略可以进一步提高网页加载速度和响应能力。

  • 强缓存: 快如闪电,过期前不问服务器。靠 Cache-Control (尤其是 max-age) 和 Expires 控制。

  • 协商缓存: 过期后问服务器“还能用吗?”。靠 ETag/If-None-Match (推荐) 和 Last-Modified/If-Modified-Since 配合工作。304 表示能用,200 表示要下载新的。

  • 核心策略: 带指纹(内容哈希)的静态资源用强缓存(长 max-age/immutable),HTML 文件用协商缓存(no-cache + ETag)。

  • 调试: 浏览器 Network 面板是你的好朋友。

  • 配置: 在服务器端(Nginx/Apache/应用服务器)设置正确的响应头

 ✅​​​​​​​HTTP 状态码与缓存类型对照表

强缓存和协商缓存在浏览器开发者工具中的可视化差异对比

特征项强缓存 (200 from cache)协商缓存 (304 Not Modified)
状态码显示200 (灰色) 且显示 (from disk cache) 或 (from memory cache)304 (浅蓝色)
Size 列显示缓存来源
(如 disk cache/memory cache
显示实际传输大小
(通常几百字节,仅头信息)
请求头无 If-None-Match/If-Modified-Since必含以下之一:
• If-None-Match: <ETag>
• If-Modified-Since: <时间>
响应头无 ETag/Last-Modified(直接从本地读取)包含:
• ETag(即使未修改)
• Last-Modified(即使未修改)
时间消耗0ms(无网络请求)几毫秒~几百毫秒(仅验证请求)
Waterfall 瀑布流无请求条目(或显示灰色短条)显示完整请求条,但传输量极短
触发条件Cache-Control: max-age 未过期Cache-Control: no-cache 或强缓存过期

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/diannao/87458.shtml
繁体地址,请注明出处:http://hk.pswp.cn/diannao/87458.shtml
英文地址,请注明出处:http://en.pswp.cn/diannao/87458.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Node.js 中的 Token 认证机制详解

文章目录 Node.js 中的 Token 认证机制详解1. Token 认证基础1.1 什么是 Token 认证&#xff1f;1.2 Token 认证流程 2. JWT (JSON Web Token) 实现2.1 安装依赖2.2 生成 Token2.3 验证 Token 中间件 3. 完整实现示例3.1 登录接口3.2 受保护的路由 4. Token 安全最佳实践5. Tok…

23 - HaLoAttention模块

论文《Scaling Local Self-Attention for Parameter Efficient Visual Backbones》 1、作用 HaloNet通过引入Haloing机制和高效的注意力实现&#xff0c;在图像识别任务中达到了最先进的准确性。这些模型通过局部自注意力机制&#xff0c;有效地捕获像素间的全局交互&#xf…

2025Mybatis最新教程(五)

第5章 ORM映射 5.1 MyBatis自动ORM失效 MyBatis只能自动维护库表”列名“与”属性名“相同时的对应关系,二者不同时,无法自动ORM。 自动ORM失效建表 create table t_managers(mgr_id int primary key auto_increment,mgr_name varchar(50),mgr_pwd varchar(50) ); 添加数据…

解决lombok注解失效问题

Lombok 注解失效是 Java 开发中的常见问题&#xff0c;通常由依赖配置、IDE 支持或构建工具设置引起。最近在拉取别人springboot3jdk21版本的项目时遇到了lombok注解失效&#xff0c;导致项目无法启动的问题&#xff0c;以下是我的解决方案&#xff1a; 首先检查idea 的lombok…

3分钟搭建LarkXR实时云渲染PaaS平台,实现各类3D/XR应用的一键推流

LarkXR是由Paraverse平行云自主研发的去中心化实时云渲染平台&#xff0c;以其卓越的性能和丰富完备的功能插件&#xff0c;引领3D/XR云化行业风向标。LarkXR适用于3D/XR开发者、设计师、终端用户等创新用户&#xff0c;可以在零硬件负担下&#xff0c;轻松实现超高清低时延的3…

vue3 watch监视详解

watch监视 一 &#xff1a;watch监视{ref}定义的基本类型结构 <template><div class"person"><h1>情况一:watch监视{ref}定义的基本类型结构</h1><h1>当前的和为{{ sum }}</h1><button click"changeSum">点我…

TensorFlow Serving学习笔记2: 模型服务

本文深入剖析 TensorFlow Serving 的核心架构与实现机制&#xff0c;结合源码分析揭示其如何实现高可用、动态更新的生产级模型服务。 一、TensorFlow Serving 核心架构 1.1 分层架构设计 TensorFlow Serving 采用模块化分层设计&#xff0c;各组件职责分明&#xff1a; 组件…

共享云桌面为什么能打败传统电脑

近年来&#xff0c;随着云桌面技术的快速发展&#xff0c;共享云桌面作为一种新型的计算模式&#xff0c;正在逐步改变人们的工作和生活方式。它凭借其独特的优势&#xff0c;正在逐步取代传统电脑&#xff0c;成为企业和个人用户的新选择。之所以在部分场景中展现出替代传统电…

B站PWN教程笔记-12

完结撒花。 今天还是以做题为主。 fmtstruaf 格式化字符串USER AFTER FREE 首先补充一个背景知识&#xff0c;指针也是有数据类型的&#xff0c;不同数据类型的指针xx&#xff0c;所加的字节数也不一样&#xff0c;其实是指针指的项目的下一项。如int a[20]&#xff0c;a是…

零基础设计模式——总结与进阶 - 3. 学习资源与下一步

第五部分&#xff1a;总结与进阶 - 3. 学习资源与下一步 到这里&#xff0c;你已经完成了设计模式主要内容的学习。但这仅仅是一个开始&#xff0c;设计模式的精髓在于实践和持续学习。本节将为你提供一些优质的学习资源和后续学习的建议&#xff0c;帮助你在这条道路上走得更…

多模态大语言模型arxiv论文略读(125)

Uni-Med: A Unified Medical Generalist Foundation Model For Multi-Task Learning Via Connector-MoE ➡️ 论文标题&#xff1a;Uni-Med: A Unified Medical Generalist Foundation Model For Multi-Task Learning Via Connector-MoE ➡️ 论文作者&#xff1a;Xun Zhu, Yi…

【学习笔记】NLP 基础概念

1.1 什么是 NLP 定义&#xff1a; 自然语言处理&#xff08;NLP&#xff09;**是一种让计算机理解、解释和生成人类语言的技术。它是人工智能领域中极为活跃且重要的研究方向&#xff0c;旨在模拟人类对语言的认知和使用过程 特点&#xff1a; 多学科交叉&#xff1a;结合计…

RNN为什么不适合大语言模型

在自然语言处理&#xff08;NLP&#xff09;领域中&#xff0c;循环神经网络&#xff08;RNN&#xff09;及衍生架构&#xff08;如LSTM&#xff09;采用序列依序计算的模式&#xff0c;这种模式之所以“限制了计算机并行计算能力”&#xff0c;核心原因在于其时序依赖的特性&a…

微信小程序一款不错的文字动画

效果图 .js Page({data: {list:[],animation:[text-left,text-right,text-top,text-bottom],text:[[春眠不觉晓&#xff0c;处处闻啼鸟。,夜来风雨声&#xff0c;花落知多少。 ],[床前明月光&#xff0c;疑是地上霜。,举头望明月&#xff0c;低头思故乡。],[千山鸟飞绝&#…

循环神经网络(RNN):序列数据处理的强大工具

在人工智能和机器学习的广阔领域中&#xff0c;处理和理解序列数据一直是一个重要且具有挑战性的任务。循环神经网络&#xff08;Recurrent Neural Network&#xff0c;RNN&#xff09;作为一类专门设计用于处理序列数据的神经网络&#xff0c;在诸多领域展现出了强大的能力。从…

手机SIM卡通话中随时插入录音语音片段(Windows方案)

手机SIM卡通话中随时插入录音语音片段&#xff08;Windows方案&#xff09; --本地AI电话机器人 上一篇&#xff1a;手机SIM卡通话中随时插入录音语音片段&#xff08;Android方案&#xff09;​​​​​​​ 下一篇&#xff1a;​​​​​​​编写中 一、前言 书接上文《手…

阿里云通义大模型:AI浪潮中的领航者

通义大模型初印象 在当今 AI 领域蓬勃发展的浪潮中&#xff0c;阿里云通义大模型宛如一颗璀璨的明星&#xff0c;迅速崛起并占据了重要的地位。随着人工智能技术的不断突破&#xff0c;大模型已成为推动各行业数字化转型和创新发展的核心驱动力。通义大模型凭借其强大的技术实…

【算法篇】逐步理解动态规划模型7(两个数组dp问题)

目录 两个数组dp问题 1.最长公共子序列 2.不同的子序列 3.通配符匹配 本文旨在通过对力扣上三道题进行讲解来让大家对使用动态规划解决两个数组的dp问题有一定思路&#xff0c;培养大家对状态定义&#xff0c;以及状态方程书写的思维。 顺序&#xff1a; 题目链接-》算法思…

什么是 HTTP Range 请求(范围请求)

HTTP Range 请求&#xff0c;即范围请求&#xff0c;是一种 HTTP 请求方法&#xff0c;允许客户端请求资源的部分数据。这种请求在处理大型文件&#xff08;如视频、音频、或大文件下载&#xff09;时特别有用&#xff0c;因为它可以有效地进行断点续传和按需加载数据&#xff…

java集合(十) ---- LinkedList 类

目录 十、LinkedList 类 10.1 位置 10.2 特点 10.3 与 ArrayList 的区别 10.4 构造方法 10.5 常用方法 十、LinkedList 类 10.1 位置 LinkedList 类位于 java.util 包下 10.2 特点 是 List 接口的实现类是 Deque 接口的实现类底层使用双向循环链表结构 10.3 与 Arra…