如何将缓存存到客户端浏览器上呢

要将缓存存到客户端浏览器,关键是让 浏览器接收到合适的 HTTP 缓存控制响应头 。这通常通过 add_header 添加控制头来实现。


✅ 一般做法(强缓存 + 协商缓存):

🔹 1. 强缓存:使用 Cache-ControlExpires

nginx 复制代码
location /static/ {
    root /path/to/static/files;
    add_header Cache-Control "max-age=3600, public";
    add_header Expires $http_expires;
}
  • max-age=3600:缓存 3600 秒
  • public:任何缓存服务器或浏览器都可以缓存
  • Expires:指定绝对过期时间(可选)

🔹 2. 协商缓存:使用 ETagLast-Modified

如果你在服务静态资源,比如:

nginx 复制代码
location /static/ {
    root /path/to/static/files;
    etag on;
    if_modified_since exact;
    add_header Cache-Control "no-cache";
}
  • 浏览器下次访问时会带 If-None-MatchIf-Modified-Since,服务器可返回 304 Not Modified

🧠 如果你是用 OpenResty 返回的 Lua 内容:

你可以手动添加缓存相关头部,例如:

lua 复制代码
ngx.header["Cache-Control"] = "max-age=60, public"
ngx.header["Expires"] = ngx.http_time(ngx.time() + 60)
ngx.say("hello world")

这样浏览器会在 60 秒内使用本地缓存,不会再请求服务端


🧪 如何验证浏览器缓存是否生效?

方法一:Chrome F12 → Network → 观察响应头

  • 状态码 200 + from memory cache 或 disk cache

  • 状态码 304 表示协商缓存命中

  • 响应头中应有:

    • Cache-Control
    • Expires
    • ETag / Last-Modified(如开启)

✅ 实战建议

静态资源使用强缓存:

nginx 复制代码
location /assets/ {
    root /usr/share/nginx/html;
    add_header Cache-Control "max-age=31536000, public";
}

动态接口用协商缓存或短时间强缓存(配合版本号或参数):

nginx 复制代码
location /api/data {
    content_by_lua_block {
        ngx.header["Cache-Control"] = "max-age=10"
        ngx.say("data at ", ngx.now())
    }
}

是不是看的云里雾里?我们来一步步详细讲解如何让 OpenResty/Nginx 将数据缓存到浏览器端(客户端),这样客户端再次访问时就不必重复请求。


🎯 目标

让浏览器缓存接口或静态资源内容,避免每次都请求服务器,提高性能。


🧱 基础概念先弄清楚

缓存类型 控制方式 浏览器行为
强缓存 Cache-Control + Expires 浏览器 不发请求,直接用本地缓存
协商缓存 ETagLast-Modified 浏览器 发请求 ,但服务器判断内容未变,返回 304,无内容体

✅ 示例一:配置强缓存(适用于静态资源)

nginx 复制代码
location /static/ {
    root /Users/yourname/openresty-static;  # 静态文件目录
    add_header Cache-Control "public, max-age=3600";
    add_header Expires $http_expires;
}

解释:

  • max-age=3600:缓存 3600 秒(1 小时)
  • public:允许任何缓存服务器(包括浏览器)缓存
  • Expires:兼容旧浏览器(用绝对时间)

🧪 测试方法

  1. 浏览器访问一次 /static/test.js
  2. 再刷新,看 Network → test.js 状态为 200 from memory/disk cache

✅ 示例二:动态接口设置缓存头(Lua 模拟)

nginx 复制代码
location /api/time {
    content_by_lua_block {
        ngx.header["Cache-Control"] = "public, max-age=30"
        ngx.header["Expires"] = ngx.http_time(ngx.time() + 30)
        ngx.say("server time: ", ngx.now())
    }
}

解释:

  • 设置响应头,告诉浏览器:30秒内请直接使用本地缓存
  • 浏览器不会向服务器请求这段时间内的 /api/time

🧪 测试方法

  1. 浏览器访问 /api/time,记录时间
  2. 再访问一次,响应不变、Network 显示 from memory cache,说明缓存生效

✅ 示例三:协商缓存(加上 ETag)

如果你服务静态文件,可以这样配置:

nginx 复制代码
location /docs/ {
    root /Users/yourname/openresty-docs;
    etag on;
    if_modified_since exact;
    add_header Cache-Control "no-cache";
}

解释:

  • etag on: Nginx 生成 ETag(唯一标识当前内容版本)
  • no-cache: 浏览器每次请求都会带 If-None-Match,服务器返回 304 表示内容没变

🧪 测试方法

  1. 第一次请求 /docs/intro.html → 返回 200
  2. 第二次请求浏览器自动带上 If-None-Match → 返回 304 Not Modified

协商缓存(Conditional Requests)机制中,浏览器每次都会带上 ETagLast-Modified 发起请求,以询问服务器是否资源有更新。

🔁 协商缓存工作机制(以 ETag 为例)

第一次请求:

  1. 浏览器访问 /example.js

  2. 服务器响应:

    复制代码
    200 OK
    ETag: "abc123"
    Cache-Control: no-cache

    浏览器会把这个 ETag 存起来。

第二次请求(浏览器再次访问):

  1. 浏览器自动带上头部:

    复制代码
    If-None-Match: "abc123"
  2. 服务器比对资源的当前 ETag 与请求的 If-None-Match

    • 如果一样 → 资源没变,返回:

      复制代码
      304 Not Modified

      无内容体,浏览器用本地缓存展示。

    • 如果不一样 → 资源已变,返回新的 200 和更新的内容与 ETag。

📦 注意:

  • 你必须显式设置 Cache-Control: no-cache,表示 "每次请求都要验证"
  • 如果你不设置,默认不会发起协商请求,可能只靠 max-age 强缓存

🚧 注意事项

  1. 接口不宜长期缓存,可以短时间缓存如 5~60 秒,用于频繁请求但数据变化不快的情况。
  2. 静态资源可以长期缓存 ,但要结合文件名加 hash,如 main.abcd1234.js
  3. 如果你用 Vue/React 构建的页面,也可以通过 nginx.conf/dist 设置缓存头

📦 常见 Cache-Control 组合参考

场景 配置示例 说明
浏览器强缓存 Cache-Control: public, max-age=86400 一天内直接使用本地缓存
协商缓存 Cache-Control: no-cache + ETag 每次请求,服务器可返回304
不缓存 Cache-Control: no-store 浏览器不保存任何内容
CDN 缓存,浏览器不缓存 Cache-Control: public, max-age=86400, must-revalidate 浏览器每次都向服务器确认

题外话:

CDN 缓存(Content Delivery Network 缓存 )是指将网站的静态资源(如图片、JS、CSS、HTML等)缓存在离用户更近的边缘节点服务器上,以提升访问速度、减轻源站压力、提升系统可用性。


🧠 一句话理解:

CDN 缓存就是:

"让用户访问 CDN 边缘节点的缓存副本,而不是每次都去请求源站"。

需要注意的是边缘节点是 CDN 服务商提供的,不是你自己买的服务器。

🧠 什么是边缘节点?

边缘节点(Edge Node)是 CDN 服务商在全国各地、甚至全球布置的缓存服务器。这些服务器靠近用户,称为"边缘"。

比如你用了阿里云 CDN,当上海的用户访问你的网站时,请求不会直接打到你自己的源站服务器,而是访问阿里云在上海部署的 CDN 节点

📦 谁提供这些边缘节点?

你不需要自己买,常见 CDN 服务商都提供大量边缘节点:

CDN 服务商 边缘节点说明
阿里云 CDN 全国几百个节点,支持全球覆盖
腾讯云 CDN 国内+海外分布式节点
百度云加速 全国部署节点
七牛云 CDN 国内主打图床/加速
Cloudflare 全球超过 300+ 城市节点
AWS CloudFront 全球 CDN 服务,适合国际化
Fastly / Akamai 国际大厂,专注北美和全球

🖼️ 举个例子帮助你理解

你的网站部署在北京阿里云的一台服务器上,用户可能来自全国各地:

用户地理位置 没有 CDN 有 CDN
北京 快(直连) 更快(边缘节点)
广州 慢(跨区访问) 快(广州本地 CDN 节点)
上海 慢(跨区) 快(上海本地节点)
美国 非常慢(跨境) 快(洛杉矶/SF 节点)

🛠️ 如何使用这些边缘节点?

  1. 你将资源部署在源站(比如你的服务器、对象存储等)

  2. 你通过 CDN 服务商的加速域名对外访问,比如:

    复制代码
    原地址:https://yourserver.com/logo.png
    CDN 加速地址:https://cdn.yourdomain.com/logo.png
  3. 用户访问的是 CDN 域名,CDN 会自动在边缘节点缓存和分发。

💡 总结一句话:

CDN 的边缘节点是 CDN 平台提供的,分布在各地,你无需部署也无需购买,只要开通使用即可享受加速服务。


🗂️ 缓存的内容类型

CDN 常缓存以下内容:

资源类型 是否常缓存
图片(.jpg/.png/.gif)
JS/CSS/字体文件
HTML 页面(根据配置) ✅(需配置)
接口数据(JSON 等) ✅(需配置)
视频/音频资源

🏗️ CDN 缓存原理

  1. 用户访问资源(如 https://cdn.example.com/logo.png

  2. CDN 边缘节点查找本地缓存:

    • ✅ 找到了(命中缓存):直接返回。
    • ❌ 没有(未命中缓存):回源到源站,取回资源 → 缓存在边缘节点 → 返回用户。
  3. 下一次其他用户访问时就直接用缓存了。


🔐 缓存控制方式(CDN 依据这些控制)

CDN 判断是否缓存/是否过期主要依赖:

响应头 说明
Cache-Control 是否缓存、缓存多久(如 max-age=600
Expires 指定过期时间(已被 Cache-Control 替代)
ETag/Last-Modified 协商缓存用,做回源时判断是否更新
Vary 用于不同 User-Agent/语言生成不同缓存副本

👉 CDN 可以配置"强缓存"或"协商缓存",也可结合自身规则(如 URL 后缀、参数名等)自定义策略。


🚀 CDN 缓存的好处

优势 描述
⚡ 提升访问速度 用户从就近节点获取资源,降低延迟
🔁 降低源站压力 静态内容不再频繁请求源站
💥 提高抗压能力 多节点分发请求,防止高峰宕机
🌍 跨地域加速 国内外访问都能快

🔧 示例:设置缓存响应头(Nginx)

nginx 复制代码
location /static/ {
    root /var/www/html;
    expires 1h;  # 设置缓存1小时
    add_header Cache-Control "public";
}

✅ 小结

问题 答案
CDN 缓存和本地缓存一样吗? 类似,都是减少重复请求。但 CDN 是服务器层缓存
CDN 缓存在哪? 缓存在 CDN 边缘节点(距离用户近的服务器)
什么时候会回源? 缓存未命中,或者缓存过期时

📌 总结

  • 想让客户端缓存数据,关键是设置好 HTTP 响应头
  • OpenResty 本身不自动帮你做浏览器缓存,你要显式加 Cache-ControlExpiresETag 等头
  • content_by_lua 里也能加 ngx.header[...] 发送这些头部
相关推荐
孙克旭_2 小时前
day037-openssh服务与http协议
linux·运维·网络·网络协议·http
周六放风筝2 小时前
生成https免费证书并绑定到nginx
linux·nginx·https
mit6.8243 小时前
[Data Pipeline] Kafka消息 | Redis缓存 | Docker部署(Lambda架构)
redis·缓存·kafka
Hello.Reader3 小时前
Redis 延迟排查全攻略
数据库·redis·缓存
jstart千语4 小时前
【Redisson】锁的可重试原理和看门狗机制
数据库·redis·缓存
ja_nus_4 小时前
三、一些好用的数据结构
redis·分布式·缓存
GGBondlctrl6 小时前
【Redis】Redis核心探秘:数据类型的编码实现与高速访问之道
数据结构·数据库·redis·缓存·编码方式·redis工作过程·单线程模型
2501_915106327 小时前
数据差异的iOS性能调试:设备日志导出和iOS文件管理
websocket·http·macos·ios·https·udp·cocoa
咖啡啡不加糖8 小时前
深入理解Redis五种基本数据类型
java·数据库·redis·缓存