静态资源热更新的关键是让浏览器放弃旧缓存并加载新内容,通过url变更(如哈希文件名)、nginx缓存头控制(expires、immutable)及配置热重载(nginx -s reload)协同实现。

实现静态资源文件的热更新,关键不在于“让旧文件消失”,而在于“让浏览器主动放弃旧缓存、加载新内容”。Nginx 本身不修改文件,但可通过 URL 变更 + 缓存头控制 + 配置重载三者协同,达成用户无感知的平滑更新。
一、核心思路:URL 变更是最可靠触发点
浏览器强缓存(Cache-Control 或 Expires)只认 URL。只要 URL 不变,即使服务端文件已更新,浏览器也可能继续用本地旧副本。
- 推荐在构建阶段为静态资源文件名注入内容哈希,例如:
/static/js/app.a1b2c3.js→ 内容变更后变为/static/js/app.d4e5f6.js - 避免仅加查询参数(如
?v=2),因部分 CDN 或代理会忽略参数做缓存合并 - ThinkPHP 等框架可配合
build.php或构建插件自动生成带哈希的文件名和模板引用
二、配合 Nginx 缓存头策略,缩短过渡期
即使 URL 已变,仍需确保新资源响应头合理,防止被错误缓存或过早失效:
- 对带哈希的静态资源(如
.js、.css、.png),配置长期缓存:location ~* \.(js|css|png|jpg|gif|ico|woff2)$ {<br> expires 1y;<br> add_header Cache-Control "public, immutable";<br>} - 对不带哈希的通用路径(如
/static/根目录),设置短缓存或禁用强缓存:location /static/ {<br> expires 1m;<br> add_header Cache-Control "no-cache, must-revalidate";<br>} - immutable 是关键:告诉浏览器该资源不会变更,允许跳过协商缓存验证,提升加载速度
三、Nginx 配置变更必须热重载,不能重启
修改完 expires 或 add_header 后,需立即生效,且不中断服务:
- 先校验语法:
nginx -t—— 确保新增的正则匹配、时间单位(1y、7d)无误 - 确认 nginx worker 进程用户(如
www-data)对配置文件有读权限 - 执行重载:
nginx -s reload—— Master 进程启动新 Worker,旧 Worker 处理完剩余请求后退出 - 验证是否生效:
curl -I https://yoursite.com/static/app.a1b2c3.js查看 Cache-Control 和 Expires 字段
四、辅助手段:日志分析 + 动态映射(进阶)
若需按访问热度差异化缓存(如热门 JS 缓存 1 年,冷门图片只缓 1 小时),可结合离线分析与 map 指令:
- 启用专用静态日志格式,按小时聚合 URI 访问频次
- 生成
/etc/nginx/conf.d/hotness.map,将路径映射为变量$cache_ttl - 在 location 中使用:
expires $cache_ttl;,每次更新 map 后 reload 即可 - 注意:
map文件本身是纯文本,无需重启,reload 即可重新加载
不复杂但容易忽略:热更新不是替换文件本身,而是切断旧 URL 的缓存链路,并确保新 URL 带正确缓存策略。真正生效的起点,永远是用户第一次请求那个带新哈希的地址。











