发版后首页变了,点进详情页还是老样式,是 CDN 没刷还是文件名没变?
发版后首页已经变了,点进详情页还是老样式,这种情况先别急着刷 CDN。按 2026 年项目交付经验,入口 HTML 换了新版本、二级页却仍是旧样式,多数不是用户手动没清缓存,而是这个页面引用的静态资源文件名没有随内容变化,或者它绕开了主构建流程,浏览器和边缘节点继续命中旧副本。判断顺序应该从离用户最近的一层往服务器方向走:先看请求有没有发出去、响应头怎么写,再决定要不要刷新 CDN。
一、先分清首页与二级页的差异来自哪一层
同一个样式包被所有页面引用时,发版应该整体生效。出现只有个别页面旧,常见有三种差异来源:一是路由级代码分割,二级页对应的是独立 chunk,它的文件名没带内容哈希;二是二级页是历史遗留的独立静态文件,压根没进构建流水线;三是页面里单独引入了第三方脚本或字体,被那一层缓存留住了。
还有一种容易误判的情况:二级页数据是接口来的,接口响应被浏览器或网关缓存,页面结构是新的、内容却是旧的。判断时先看元素级样式有没有变,再看文字内容,两者能区分是资源缓存问题还是接口缓存问题。
- 样式和内容都旧:多半是 HTML 或整包资源命中强缓存。
- 样式变了、内容旧:往接口响应缓存和网关 proxy_cache 方向查。
- 只有某一个页面旧:优先看这个页面的 chunk 是否带内容哈希、是否走了构建。
二、强缓存和协商缓存,先判断属于哪一类
强缓存由 Cache-Control 的 max-age 或 Expires 控制,命中后浏览器在有效期内直接用本地副本,请求不会到服务器,服务端日志里看不到痕迹;协商缓存由 ETag、Last-Modified 控制,浏览器每次都会发请求,服务端返回 304 才复用本地副本。
对发版不生效来说,强缓存麻烦在于有效期内服务端无法撤回。按 2026 年常见做法:
- 带内容哈希的资源:CSS、JS、图片、字体可以设较长强缓存,常见区间 30 天到 1 年,内容变了文件名就变了。
- 入口 HTML:建议 no-cache 或把 max-age 控制在 0~60 秒,保证每次能拿到新的资源引用。
- 接口响应:默认不加长强缓存,需要时用业务版本字段控制,不要只靠 Cache-Control。
另外要提醒的是,文件名不变比缓存时间设长了更难处理。内容改了文件名还是 app.js,浏览器和 CDN 都认为还是同一份文件,会一直用旧副本,直到强缓存自然过期。只要文件名随内容哈希变化,即使缓存时间设得很长,用户下次打开新 HTML 也会引用到新文件。
三、按五层顺序逐层定位
这个顺序按离用户从近到远划分,每层都有验证手段,避免一上来就做代价高的操作。多数项目查到第二三层就能定位,不必五层全走一遍。
- 浏览器 HTTP 缓存:让用户用无痕窗口打开,或在开发者工具里勾选禁用缓存。若正常,问题在本地强缓存,回到资源策略本身修正。
- Service Worker 或离线缓存:站点注册过 Service Worker 时,它会拦截请求并返回自己缓存的副本,清浏览器缓存也未必生效,需要在代码里更新缓存版本并处理旧版本卸载。
- CDN 边缘节点:换网络或换地区访问,结果不同说明不同节点缓存不一致,按 CDN 控制台的刷新规则提交,注意刷新生效常需要几分钟到十几分钟。
- 中间层 Nginx 或网关缓存:检查是否开了 proxy_cache,缓存键里有没有带版本或哈希。开了缓存又没设失效条件,是很容易被忽略的一层。
- 后端模板或 SSR 输出:服务端渲染的 HTML 如果被写入本地缓存或分片缓存,也可能吐出旧结构,要核对渲染层有没有按版本失效。
排查的关键是先确认请求有没有真正到达服务端。跳步的结果通常是刷了一圈缓存,问题还在。
四、几种做法对比,按项目体量选
治理方式不止一种,成本差别不小。按 2026 年常见交付经验,中大型对外站点适合「入口短缓存 + 资源内容哈希 + CDN 刷新」的组合;小项目或内部系统用更简单的做法就够,没必要搭一套完整发布链路。
- 入口不缓存 + 资源内容哈希:适用对外站点、H5、单页应用;改造周期常见 1~3 人天,涉及构建配置和网关缓存头;长期维护成本低,是多数情况下的默认做法。
- URL 加版本号参数:适用静态页少、构建流程简单的小站;初始改动常见半天以内,但版本参数要人工维护,页面数一多就容易漏改。
- 目录级别切换:适用整站改版或需要灰度对比的场景;切换干净,但旧目录要保留,占存储,也要事先约定下线时间。
- 页面内提示刷新:只作兜底,不能当主方案;对不愿升级的长尾用户有些帮助,体验一般。
交付现场常见的情况是:预算和周期都紧,甲方希望一次上线解决所有缓存问题,但旧页面已经流出、边缘节点上还留着老文件。比较稳妥的做法是先把入口 HTML 从长强缓存改成协商缓存,再给资源文件名补上内容哈希,同时按 CDN 规则提交一次刷新。代价是旧文件要保留一段时间以备回滚,一个发布周期内的验证和改稿大概会占半个迭代;如果 CDN 刷新需要走审批流程,发布窗口还要再往前排。犀跃公司在落地这类改动时,一般会先确认刷新审批和回滚路径,再动缓存头。
五、什么情况适用,什么情况不必上复杂方案
分层缓存这套做法的前提是资源变更频繁、用户端版本不可控。符合这个前提的是带 CDN 的对外站点、移动端 H5,以及用 WebView 承载的页面。反过来,纯内网管理系统用户固定、发版可以约定时间、也不经过 CDN,直接让用户强刷一次就够,为它引入完整哈希流水线反而增加发布负担。
另有两类建议简化:一是以后端接口为主的服务,本身不产出静态资源,缓存治理重点在接口响应和网关,不在前端文件;二是只有几个静态页的展示站,文件名手工加版本号比接一套构建更省事。判断标准可以简化成一句:用户端版本不可控、资源变更频率高,就做分层;两者缺一,可以先记录现状,等出现实际投诉再改造,不必提前上复杂链路。
常见问题
入口 HTML 到底要不要设置不缓存?
建议用 no-cache 走协商缓存,或把 max-age 控制在 0~60 秒。直接设一年强缓存,等于每次发版都要等用户缓存过期才生效。
资源名带了哈希,为什么还有用户说页面没更新?
多数是入口 HTML 仍被强缓存,用户拿到的是旧 HTML,引用的自然还是旧文件名。先核对入口文件的缓存头,再确认哈希是否随内容变化。
微信里打开一直不更新,和浏览器缓存是一回事吗?
不完全一样。内置浏览器的缓存策略更保守,入口也更难清理,所以入口 HTML 走协商缓存、资源名带内容哈希这两条要先做扎实。
出问题后刷一次 CDN,是不是就都好了?
不一定。刷 CDN 只作用于边缘节点那一层,用户浏览器里的强缓存副本仍在,只有入口改成协商缓存,下次访问才会真正拿到新入口。
只有二级页旧,能不能单独刷那个页面的缓存?
可以,但要先确认这个页面的资源是否带内容哈希。如果文件名没变,刷完很快又会被缓存成旧内容,属于治标做法。
如果你的站点有 CDN、发版频率高、用户端版本不可控,优先把入口 HTML 改成短缓存或协商缓存,再补齐资源内容哈希,这两步能覆盖大部分旧页面反馈。若资源本来就不常改、用户集中在可控环境,可以先记录现状,等出现实际投诉再改造。
-
同一个订单的支付和发货消息前后颠倒,每次都等队列自己排,顺序该不该在消费端自己保?
日期:2026年10月15日 阅读:72
-
运营每周都要改活动开关,每次都找研发发版,配置该不该挪到配置中心?
日期:2026年10月14日 阅读:69
-
上线后 OPTIONS 预检一直 401,跨域头也加了,为啥浏览器还报跨域?
日期:2026年10月13日 阅读:103
-
列表翻页第二页又出现上一页最后一条,前端按主键去重就能先上线吗?
日期:2026年10月12日 阅读:50
-
同一笔支付回调来了三次,货发了两回,只加唯一索引算防住了吗?
日期:2026年10月11日 阅读:38




