当前位置: 首页 > ds >正文

强缓存与协商缓存的实现机制

文章目录

  • 前言
    • **1. 强缓存(强制缓存)**
    • **强缓存生效流程**:
    • **2. 协商缓存(对比缓存)**
    • **协商缓存生效流程**:
    • **对比总结**
    • **实际应用建议**
  • **1. 缓存配置的三种主要实现方式**


前言

强缓存与协商缓存的实现机制

1. 强缓存(强制缓存)

特点:浏览器直接从本地缓存读取资源,不发送请求到服务器。
实现方式:通过 Cache-ControlExpires 响应头控制。

(1) Cache-Control(HTTP/1.1 标准,优先级更高)
• 常见指令:

max-age=<seconds>:缓存有效期(如 max-age=3600 表示 1 小时内有效)。

no-cache:不使用强缓存,直接进入协商缓存(向服务器验证)。

no-store:完全禁用缓存,每次请求都重新获取资源。

public:允许代理服务器缓存(默认 private 仅浏览器缓存)。

immutable:资源永不变,浏览器直接使用缓存(适用于版本化文件名如 main.a1b2c3.js)。

• 示例:

Cache-Control: public, max-age=3600

(2) Expires(HTTP/1.0 遗留,优先级低于 Cache-Control
• 指定一个绝对过期时间(GMT 格式),若本地时间超过该时间则缓存失效。

• 示例:

Expires: Wed, 21 Oct 2025 07:28:00 GMT

强缓存生效流程

  1. 浏览器请求资源时,检查 Cache-Control/Expires
  2. 若未过期,直接从 内存缓存(Memory Cache) 或 磁盘缓存(Disk Cache) 加载,HTTP 状态码显示 200 (from cache)。
  3. 若已过期,进入协商缓存流程。

2. 协商缓存(对比缓存)

特点:浏览器向服务器验证缓存是否有效,可能返回 304(Not Modified) 继续使用缓存。
实现方式:通过 Last-Modified/If-Modified-SinceETag/If-None-Match 两组头部控制。

(1) Last-Modified + If-Modified-Since
• 服务器返回 Last-Modified:资源的最后修改时间(GMT 格式)。

• 浏览器下次请求:携带 If-Modified-Since(值为上次的 Last-Modified)。

• 服务器检查:

• 若资源未修改(时间未变),返回 304 Not Modified,浏览器使用缓存。

• 若已修改,返回 200 OK 和新资源。

• 示例:

# 首次请求(服务器响应)
Last-Modified: Wed, 21 Oct 2025 07:28:00 GMT# 再次请求(浏览器携带)
If-Modified-Since: Wed, 21 Oct 2025 07:28:00 GMT

(2) ETag + If-None-Match(更精准)
• 服务器返回 ETag:资源的唯一标识符(如哈希值)。

• 浏览器下次请求:携带 If-None-Match(值为上次的 ETag)。

• 服务器检查:

• 若 ETag 匹配,返回 304 Not Modified。

• 若不匹配,返回 200 OK 和新资源。

• 示例:

# 首次请求(服务器响应)
ETag: "33a64df551425fcc55e4d42a148795d9"# 再次请求(浏览器携带)
If-None-Match: "33a64df551425fcc55e4d42a148795d9"

协商缓存生效流程

  1. 浏览器发现强缓存失效(或 no-cache),携带 If-Modified-SinceIf-None-Match 向服务器发起请求。

  2. 服务器验证资源是否变化:
    • 未变化 → 返回 304,浏览器使用缓存。

    • 已变化 → 返回 200 和新资源。


对比总结

缓存类型实现方式优先级特点
强缓存Cache-Control/Expires直接读缓存,不请求服务器。
协商缓存Last-Modified/ETag需向服务器验证,可能返回 304。

实际应用建议

  1. 静态资源(如 JS/CSS/图片):
    • 使用强缓存 + 文件名哈希(如 main.a1b2c3.js),设置 Cache-Control: max-age=31536000, immutable

  2. 动态资源(如 API 数据):
    • 使用 Cache-Control: no-cache + ETag,确保实时性。

  3. 避免缓存问题:
    • 修改资源时更新文件名或 URL 参数(如 ?v=2)。

通过合理配置,可显著减少网络请求,提升页面加载速度! 🚀


1. 缓存配置的三种主要实现方式

(1) 后端代码控制(如Node.js/Java/Python)
适用场景:动态API、需要业务逻辑判断是否缓存。
示例(Node.js Express):

app.get('/data', (req, res) => {// 强缓存:1小时有效res.set('Cache-Control', 'public, max-age=3600');// 协商缓存:ETagconst data = { id: 1, name: 'Example' };const etag = require('crypto').createHash('md5').update(JSON.stringify(data)).digest('hex');res.set('ETag', etag);// 检查客户端If-None-Matchif (req.headers['if-none-match'] === etag) {return res.status(304).end(); // 返回304,使用缓存}res.json(data);
});

(2) Web服务器配置(如Nginx/Apache)
适用场景:静态资源(HTML/CSS/JS/图片)的缓存。
Nginx示例:

server {location /static/ {# 强缓存:1年(适用于版本化文件名如main.a1b2c3.js)add_header Cache-Control "public, max-age=31536000, immutable";# 协商缓存:Last-Modified/ETag(默认启用,无需额外配置)}location /api/ {# 动态接口禁用强缓存,只用协商缓存add_header Cache-Control "no-cache";# Nginx会自动处理ETag/Last-Modified(需确保后端未覆盖)}
}

(3) CDN控制(如Cloudflare/AWS CloudFront)
适用场景:全球加速的静态资源缓存。
Cloudflare规则示例:
• 缓存规则:匹配URL路径(如/images/*),设置缓存有效期(如1小时)。

• 边缘缓存TTL:覆盖源站的Cache-Control头。


2. 缓存策略选择与优先级
(1) 缓存配置的优先级

  1. CDN设置 > Nginx配置 > 后端代码
    • 如果CDN设置了缓存规则,它会覆盖Nginx或后端的Cache-Control头。

    • 如果Nginx配置了add_header,它会覆盖后端代码的响应头。

(2) 如何决定使用哪种方式?

场景推荐方式理由
静态资源(JS/CSS/图片)Nginx/CDN高效、无需业务逻辑,直接通过文件名哈希(如main.a1b2c3.js)和强缓存优化。
动态API数据后端代码需要根据业务逻辑判断是否缓存(如用户隐私数据不可缓存)。
全局缓存策略CDN统一管理所有边缘节点的缓存行为,适合多地域部署。

(3) 强制禁用缓存的场景
• 需要实时数据的API(如股票价格):

Cache-Control: no-store

• 用户敏感信息(如个人资料):

Cache-Control: private, no-cache

3. 实战建议
(1) 静态资源优化

location /assets/ {# 文件名带哈希(如main.a1b2c3.js),强缓存1年add_header Cache-Control "public, max-age=31536000, immutable";
}

• 使用Webpack/Vite等工具生成哈希文件名,确保内容变化后URL改变。

(2) 动态API优化

// 后端代码(Express/Koa)
res.set({'Cache-Control': 'no-cache', // 禁用强缓存,但允许协商缓存'ETag': generateETag(data)   // 基于内容生成ETag
});

(3) 调试缓存行为
• Chrome DevTools → Network → 查看请求头(Cache-Control/ETag)和响应状态(200/304)。

• cURL命令测试:

curl -I http://example.com/resource
# 检查响应头中的Cache-Control/ETag

总结
• 谁控制缓存?

• 静态资源 → Nginx/CDN

• 动态API → 后端代码

• 全局策略 → CDN

• 如何选择?

• 强缓存:Cache-Control: max-age=3600(Nginx/CDN优先)。

• 协商缓存:ETag/Last-Modified(后端或Nginx自动处理)。

• 调试工具:Chrome DevTools、cURL、Web服务器日志。

合理配置缓存可显著提升性能,减少服务器压力! 🚀

http://www.xdnf.cn/news/4540.html

相关文章:

  • AKS 网络深入探究:Kubenet、Azure-CNI 和 Azure-CNI(overlay)
  • 基于LVS实现负载均衡,对NAT模式的介绍和使用案例
  • LeetCode第190题_颠倒二进制位
  • 云蝠智能大模型语音交互智能体赋能电视台民意调研回访:重构媒体数据采集新范式
  • 2:点云处理—3D相机开发
  • 如何在Idea中编写Spark程序并运行
  • 【Bug经验分享】SourceTree用户设置必须被修复/SSH 主机密钥未缓存(踩坑)
  • Windows_PyCharm Python语言开发环境构建
  • 常见dp问题的状态表示
  • MCPHub:一站式MCP服务器聚合平台
  • CI/CD与DevOps流程流程简述(给小白运维提供思路)
  • Spring AI(1)—— 基本使用
  • QT中connect高级链接——指针、lambda、宏
  • 基于Qt的app开发第六天
  • 如何理解k8s中的controller
  • 缓存菜品-01.问题分析和实现思路
  • Carlink 技术:搭建汽车与手机的智能桥梁
  • GPAW安装流程——Ubuntu 系统(Python 3.8.10)
  • AI视觉质检的落地困境与突破路径
  • 工业现场ModbusTCP转EtherNETIP网关引领生物现场领新浪潮
  • gcloud 查看gke集群节点组是否开启了自动伸缩?
  • CAN报文逆向工程
  • node.js 实战——餐厅静态主页编写(express+node+ejs+bootstrap)
  • LangChain4j简介
  • Android开发-文本显示
  • 【2019 CWE/SANS 25 大编程错误清单】12越界写入
  • dubbo-token验证
  • 路由器WAN口和LAN口
  • 大数据技术全景解析:Spark、Hadoop、Hive与SQL的协作与实战
  • UE5 Audio2Face导出USD表情与ARKIT表情重定向