这个坑最近特别多人踩——91网:关于缓存设置的说法 | 这次终于说清楚…如果属实,那就太刺激了

引子
最近围绕“91网”的缓存设置讨论火得一塌糊涂,很多技术人、运营和产品在群里转发截图,怀疑网站被误配置为“把静态资源不缓存、把页面长期缓存”或反过来,导致用户看到旧内容或频繁拉取资源。把技术说白了:缓存设置搞不好,既影响体验,又影响成本和搜索引擎抓取。本篇把常见坑、排查方法和可行修复一步步讲清楚,方便你快速判断“如果属实,那到底有多刺激”,并给出可直接落地的建议。
缓存基础快速回顾(2分钟读懂)
- 浏览器缓存:由 HTTP 响应头(Cache-Control、Expires、ETag、Last-Modified)和 Service Worker 控制,决定浏览器是否复用本地资源。
- 中间缓存(CDN / 反向代理):CDN 与边缘节点会根据响应头和缓存策略决定是否缓存并返回缓存副本。
- 缓存粒度:HTML 页面通常不能长期缓存(除非有版本机制),静态资源(js/css/png)则适合长期缓存并用文件指纹做更新。
- 常见头含义:Cache-Control: public/private/no-cache/no-store/max-age;ETag、Last-Modified 用于协商缓存。
91网争议点:常见传闻与技术上可能的真相
- 传闻 A:HTML 被设置为极长的 max-age,用户看不到最新页面。
可能原因:部署模板生成器或 CDN 配置错误,把 HTML 当静态资源处理并设置了 long-lived 缓存。也可能是误用 Service Worker 导致离线缓存策略过 aggressive。
- 传闻 B:静态资源根本不缓存,导致每次加载都去源站拉资源,带宽暴涨。
可能原因:缺少 Cache-Control 或设置为 no-cache/no-store;CDN 的缓存规则覆盖;URL 带有未处理的 query string 干扰缓存。
- 传闻 C:ETag/Last-Modified 行为导致频繁发起 304 判断(看似没有缓存)。
可能原因:ETag 每次由部署工具或文件系统生成不同值,或服务器时间不稳定导致 Last-Modified 不一致。
这些都是真实项目中常见且容易被忽视的问题。
几个典型踩坑实录(为什么很多人会中招)
- 把整个站点放到静态托管后,默认把所有文件设置同样的 long max-age,结果 HTML 页面也“被指纹化”出问题。
- 为了方便调试开发,把 Cache-Control 设成 no-cache,上线忘删,带来性能问题。
- 部署自动化每次构建都会更改 ETag,导致客户端每次都发送 If-None-Match 请求,无法真正减少带宽。
- 使用 Service Worker 离线缓存策略时,忘了处理更新逻辑,用户长期看到旧版缓存 UI。
- CDN 配置冲突:源站设置与 CDN 覆盖规则矛盾,导致实际生效与预期不符。
快速检测与验证方法(实用命令与工具)
- curl 检查响应头:
curl -I https://example.com/page
重点看 Cache-Control、Expires、ETag、Last-Modified、Vary 等头。
- 模拟强制缓存与协商缓存测试:
curl -H "Cache-Control: max-age=0" -I https://example.com/resource
curl -H "If-None-Match: " -I https://example.com/resource
- 浏览器开发者工具:Network 面板看 Size、Status(200 vs 304 vs (memory cache))、Timing。
- Lighthouse / WebPageTest:查看缓存命中率与资源建议。
- CDN 控制台检查:缓存命中率、edge 配置、缓存规则、Query String 处理策略。
- 检查 Service Worker:Application > Service Workers,看是否有激活的 SW 与其 fetch 逻辑。
实战修复建议(按资源类型给出可直接复制的策略)
总体原则(简明版):
- HTML:短缓存或协商缓存,并通过页面版本控制实现即时更新(例如:Cache-Control: no-cache, must-revalidate 或 max-age=0)。
- 静态资源(js/css/img/fonts):长期缓存 + 文件指纹(例如 filename.abcdef.js),配合 Cache-Control: public, max-age=31536000, immutable。
- 动态或带权限的响应:private/no-store/指定 Vary(如 Authorization、Cookie)。
- Service Worker:实现合理更新流程(skipWaiting/clients.claim + 更新检测),并在资源变更时清除旧缓存。
Nginx 推荐片段(常见且可直接使用)
- 静态资源长期缓存:
location ~* .(?:css|js|woff2|woff|ttf|png|jpg|jpeg|gif|svg)$ {
expires 30d;
add_header Cache-Control "public, max-age=2592000, immutable";
}
- HTML 页面短缓存/协商缓存:
location / {
tryfiles $uri $uri/ /index.html;
addheader Cache-Control "no-cache, must-revalidate";
}
- 对于需要 CDN 遵循的 header 可加:
addheader ETag $upstreamhttp_etag;
# 或者在需要时禁用 ETag:etag off;
Apache 推荐片段(.htaccess)
- 静态资源:
Header set Cache-Control "public, max-age=2592000, immutable"
- HTML:
Header set Cache-Control "no-cache, must-revalidate"
Cloudflare / CDN 注意事项
- Cloudflare 默认会缓存静态资源,页面缓存策略以 origin headers 为准或按 Page Rules。确认是否有 Page Rule 覆盖 origin 的 max-age。
- Query string:部分 CDN 可配置“忽略 query string”或“视不同 query string 为不同缓存资源”。缓存键策略要和你的缓存破坏/版本策略一致。
- Purge:上线更新后记得自动触发 CDN 清除(或使用带版本号的资源避免 purge)。
Service Worker 的特有坑与对策
- 离线缓存策略过激会导致用户长期看到旧内容。用“网络优先 + 缓存回退”或“缓存优先但加上线下更新提示”更稳妥。
- 更新 SW 时使用 clients.claim() + skipWaiting(),并在新的资源可用时通知前端触发刷新或按需更新。
- 在 SW 中对版本化资源不要再做长期缓存策略的二次控制,保持与 HTTP header 一致。
如何在发布流程中把缓存问题“彻底关死”
- 强制静态资源带指纹(hash)文件名,部署时不要改变已发布文件名。
- CI/CD 在部署成功后自动触发 CDN purge(仅针对需要即时失效的资源)。
- 在构建产物中记录版本号,页面注入版本号供前端检查(例如 window.APP_VERSION)。
- 建立回滚与验证流程:发布后 5–15 分钟内用自动化脚本验证关键页面的缓存头与资源加载行为。
- 避免把“开发时”的缓存头带到生产环境(例如开发环境常用 no-cache,部署脚本应切换配置)。
如何判断“如果属实,那就太刺激了”到底有多严重
- 对用户体验的影响:页面长期缓存会导致用户看不到最新活动、价格或内容,直接影响转化;静态资源不缓存会导致首页加载时间显著上升。
- 对成本的影响:源站带宽与 CPU 浪费,CDN 命中率低会让流量费用激增。
- 对 SEO 与抓取的影响:错误的缓存头与 301/302 配合不当可能影响搜索引擎抓取节奏,影响索引。
综合这些维度,若真的出现“HTML 长期缓存 + 静态不缓存”这类明显反常配置,后果确实“刺激”:既砸体验又砸钱。
落地检查清单(发布前后快速 8 项)
- curl -I 检查首页与静态资源的 Cache-Control/Expires/ETag/Last-Modified。
- 确认静态资源文件名是否带 hash(版本号)。
- CDN 控制台查看缓存命中率统计并核对 Page Rules。
- 浏览器 DevTools 真实用户视图:首次加载 vs 刷新 vs 断网加载。
- 检查 Service Worker 是否激活与其 fetch 策略。
- 用 Lighthouse 看缓存改进项(Performance > Serve static assets with an efficient cache policy)。
- 部署后触发自动化脚本验证关键 URL。
- 若出现问题,立即执行 CDN purge 或回滚到已知正确配置。
结语
关于“91网的缓存设置”这类争议,技术上多数能被排查和修复:先用工具验证真实 headers,再看是否为 CDN/Service Worker/部署脚本的问题。真正刺激的情形是那种在生产环境里把缓存策略完全弄反,导致体验与成本双重问题——遇到就该迅速定位与修复。按上面的检测步骤和配置建议走一遍,大多数坑都能踩不着,踩着了也能快速复原。