HTTP 缓存策略 Cache-Control 与 ETag 实战:让接口又快又不出错

举报
yd_214683010 发表于 2026/11/02 06:09:31 2026/11/02
【摘要】 很多接口变慢,问题并不在数据库或代码逻辑,而在重复请求上:同一个静态资源、同一份字典数据、同一页列表,被浏览器和 CDN 一遍遍重新拉取。HTTP 缓存就是用来省掉这些重复劳动的,但用错了反而会让用户看到旧数据。本文用 Cache-Control 与 ETag 这一对组合,给出一套可直接落地的分层做法。 一、先分清两种缓存强缓存由浏览器自己判断,不发请求。服务器在响应里写:Cache-Con...

很多接口变慢,问题并不在数据库或代码逻辑,而在重复请求上:同一个静态资源、同一份字典数据、同一页列表,被浏览器和 CDN 一遍遍重新拉取。HTTP 缓存就是用来省掉这些重复劳动的,但用错了反而会让用户看到旧数据。本文用 Cache-Control 与 ETag 这一对组合,给出一套可直接落地的分层做法。

一、先分清两种缓存

强缓存由浏览器自己判断,不发请求。服务器在响应里写:

Cache-Control: public, max-age=3600

在 max-age 有效期内,浏览器直接用本地副本,速度最快,也最省带宽。

协商缓存则要发一次轻量请求问服务器:我手里的版本还新吗?服务器返回 304,说明没变,浏览器继续用本地副本;返回 200,则带回新内容。强缓存管“能不能不问”,协商缓存管“问了之后要不要重新下载”。

二、Cache-Control 的常用写法

  • public, max-age=31536000, immutable:适合带内容哈希文件名的 JS、CSS、图片,文件名一变就是新资源,旧缓存不会误伤。
  • private, max-age=60:只允许浏览器缓存,不允许共享缓存存用户相关内容,适合个人化但变化不快的页面片段。
  • no-cache:不是“不缓存”,而是每次使用前必须先向服务器验证,适合经常变但又想省下 304 之后传输量的接口。
  • no-store:任何地方都不要存,适合订单、支付结果、含敏感信息的响应。

容易踩的坑是把 max-age 和 no-cache 混在一起写,却以为前者会生效;实际语义以后者为准,先验证再用。

三、ETag:给资源一个版本号

ETag 是服务器给某个版本资源贴的标识,内容一变标识就应变。浏览器下次请求时带上它:

If-None-Match: "v123"

服务器比对后若一致返回 304 且不带正文,只花一次往返;若不一致返回 200 与新内容。比 Last-Modified 更可靠,因为它不依赖秒级时间精度,也能区分同一秒内多次改动。弱 ETag 以 W/ 开头,表示语义相同但字节可能不同,适合经过压缩或格式转换仍可复用的场景。

四、实战分层建议

第一层是静态资源:构建时生成带哈希的文件名,配一年长缓存加 immutable,发布新版不用清缓存,旧页面也不会引用错文件。入口 HTML 本身不要长缓存,用 no-cache 加 ETag,改版后用户刷新即可拿到新入口。

第二层是读多写少的接口:字典、配置、公开榜单等,配 private, max-age=60 或 no-cache,并返回稳定的 ETag。内容不变时一次 304 就结束,带宽和后端压力都下来了。

第三层是个人数据与写操作结果:用 no-store,不要为了省一次请求让下一位用户或同一台共用设备看到别人的数据。POST、PUT、DELETE 本来就不应被当作可缓存的 GET 来处理。

五、上线前自查清单

  1. 用 curl -I 看响应头,确认强缓存与协商缓存没有互相矛盾。
  2. 确认 CDN 与反向代理没有私自去掉 ETag,也没有把 Vary 丢掉导致不同语言或压缩版本串味。
  3. 多节点部署时,ETag 生成方式要一致,否则同一资源在不同节点上来回 200,缓存等于失效。
  4. 改版后先看入口 HTML 是否 304、静态文件名是否真的变了,再看接口是否按预期返回 304。

缓存的目标不是把所有东西都存起来,而是把“不变的东西少传、常变的东西及时验”。先按资源变化频率分层,再用 Cache-Control 定有效期、用 ETag 做版本校验,接口自然会又快又稳。

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0)

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。