nginx通过rewrite重写旧路径并配合try_files兜底,实现静态资源平滑版本切换:如将/static/v1/js/app.js映射到/assets/js/app.js,未命中时回退原路径或报404,并通过自定义日志追踪收敛进度。

用 Nginx 实现静态资源的平滑版本切换,关键是在不改前端代码、不触发重定向、不中断加载的前提下,让新旧路径共存并逐步收敛。核心手段是 rewrite 主动映射 与 try_files 被动回退 的组合使用,配合日志追踪和渐进验证。
明确新旧路径映射关系
切换前必须理清资源位置变化。例如:
- 旧路径为
/static/v1/js/app.js,新版统一放在/assets/js/app.js - HTML 和 CSS 中仍大量引用
/static/v1/开头的 URL,不能立刻批量修改源码 - 目标是:请求
/static/v1/js/app.js时,Nginx 先按原路径找,找不到就自动查/assets/js/app.js
用 rewrite 实现内部路径重写
在匹配旧路径的 location 块中,用 rewrite 把请求 URI 映射到新结构,推荐使用 last 标志确保后续规则(如 try_files)继续生效:
- 简单目录迁移:
location /static/v1/ {<br> rewrite ^/static/v1/(.*)$ /assets/$1 last;<br>} - 处理带哈希的文件名(如
/static/v1/js/app.a1b2c3.js→/assets/js/app.js):location ~ ^/static/v1/(js|css|img)/(.+)\.[a-f0-9]{8,}\.(js|css|png|jpg|gif)$ {<br> rewrite ^/static/v1/(js|css|img)/(.+)\.[a-f0-9]{8,}\.(js|css|png|jpg|gif)$ /assets/$1/$2.$3 last;<br>}
用 try_files 提供兜底容错
rewrite 是主动改,但若新路径也不存在(比如资源还没发布或路径写错),需 fallback 到旧路径或直接报错。搭配 try_files 可避免 404 中断:
- 先查 rewrite 后路径,再查旧路径,最后 404:
location /static/v1/ {<br> alias /var/www/new-site/assets/;<br> try_files $uri /assets/$uri =404;<br>} - 更稳妥的做法是把 rewrite 和 try_files 放在同一 location,形成“重写→查找→回退”链路,兼顾灵活性与健壮性。
通过日志追踪收敛进度
上线后需知道哪些旧路径还在被访问,才能针对性补资源或推动前端更新。添加自定义日志格式记录回退行为:
- 定义日志格式:
log_format migration '$remote_addr - $request_uri → $status (via try_files)'; - 启用日志:
access_log /var/log/nginx/migration.log migration; - 定期检查该日志,统计高频未命中请求,逐步清理旧引用或补全新资源,直到日志归零。











