实现无感知内容更新需浏览器与nginx协同:静态资源用哈希url+immutable头长期缓存;html入口禁强缓存,由nginx动态控制;api按状态码分级缓存并启用stale容错;提供purge清理和bypass绕过接口。

实现无感知的内容更新,关键不是让旧内容“立刻消失”,而是让新内容“自然接管”——用户不刷新、不报错、不卡顿,浏览器和 Nginx 协同完成平滑过渡。这需要同时管控客户端缓存(浏览器)和代理缓存(Nginx),且两者策略要错开节奏、互为兜底。
静态资源:靠 URL 变更 + immutable 头锁定更新节奏
JS/CSS/图片等静态文件一旦被浏览器强缓存,改服务端文件也没用。真正有效的做法是让每次构建生成带内容哈希的文件名(如 app.f3a8b2.js),确保内容变则 URL 变。
- 在 Nginx 中对这类带哈希的资源启用长期缓存:
location ~* \.(js|css|png|woff2)$ { expires 1y; add_header Cache-Control "public, immutable"; } - immutable 是重点:它告诉浏览器“这个 URL 永远不会变”,跳过协商缓存(ETag/Last-Modified),既提速又防误判
- 避免只加查询参数(如 ?v=20260613),因为 CDN 或中间代理可能忽略参数做缓存合并
HTML 页面:禁长期缓存,把控制权交还给 Nginx
HTML 是静态资源的“入口”,必须保持灵活。它不能缓太久,否则用户加载了旧 HTML,就会一直引用旧 JS,再新的资源也白搭。
- 对 /index.html、/entry.html 等主入口,设极短缓存或禁用强缓存:
location = /index.html { expires -1; add_header Cache-Control "no-cache, must-revalidate"; } - 这样每次访问都会向 Nginx 发起请求,由 Nginx 决定返回哪个后端版本(灰度/全量)、是否插入新资源路径,甚至动态替换 script 标签
- 若需灰度,可在 Nginx 里用
map或if判断 cookie 或 header,差异化输出 HTML 内容
动态接口:用后台更新 + stale 容错保可用性
API 响应内容常变,但完全不缓存会压垮后端。合理缓存 + 智能失效,才能兼顾性能与新鲜度。
- 按状态码分级设置有效期:
proxy_cache_valid 200 302 60s;(高频列表类)proxy_cache_valid 404 5m;(兜底页可稍长)proxy_cache_valid any 0s;(登录态、支付页直接不缓存) - 开启后台更新:
proxy_cache_background_update on;—— 缓存过期时,Nginx 立即返回旧数据,同时悄悄拉新 - 搭配
proxy_cache_use_stale updating error timeout http_500;,即使后台拉取失败或超时,仍可用旧缓存顶上,用户完全无感
主动干预:提供 purge 和 bypass 接口快速响应发布
自动策略应对日常更新,但发布后需“立刻生效”时,得有运维入口。
- 启用 ngx_cache_purge 模块,配置安全的 PURGE 路径:
location ~ /purge(/.*) { allow 127.0.0.1; deny all; proxy_cache_purge my_cache $host$1$is_args$args; } - 通过 curl 触发清理:
curl -XPURGE https://example.com/api/v1/news,精准清除指定接口缓存 - 对紧急上线,用自定义头绕过缓存并重建:
proxy_cache_bypass $http_x_cache_bypass;<br>proxy_no_cache $http_x_cache_bypass;
然后发带X-Cache-Bypass: 1的请求,强制回源并落新缓存











