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

要将缓存存到客户端浏览器,关键是让 浏览器接收到合适的 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[...] 发送这些头部
相关推荐
nvd1132 分钟前
GCP 7层 外部 HTTP 负载均衡器深度解析
网络协议·http·负载均衡
踏着七彩祥云的小丑18 小时前
忘记Redis是否安装过时查看
数据库·redis·缓存
雾里0不看花1 天前
.NET通过HTTP操作MINIO
http·.net·iphone
麻瓜code1 天前
【Redis 】数据类型、持久化与过期删除
数据库·redis·缓存
不在逃避q1 天前
使用.NET实现自带思考的Tool 并且提供mcp streamable http服务
网络协议·http·.net
changshuaihua0011 天前
Redis 详解:Redis 与 MySQL 的区别、数据类型与缓存三大问题
数据库·redis·缓存
love530love1 天前
Windows 原生编译 SGLang(4/8):环境关——VS 版本、venv 顺序、CUDA 多版本、生成器缓存
windows·缓存·sglang
一条泥憨鱼1 天前
【从0开始学习计算机网络】| HTTP方法疑点解析
开发语言·计算机网络·http
一条泥憨鱼1 天前
【从0开始学习计算机网络】| RESTful API 设计原则
计算机网络·http·restful api
外滩运维专家1 天前
HTTPS 证书报错排查手册:6 个高频错误码及解决方法
网络协议·http·https