rewrite实现静态资源平滑过渡的核心是不改变用户URL而内部重写路径,适用于路径结构调整与版本目录切换,需在匹配location中配置,推荐使用last标志进行内部重写,配合try_files提供兜底保障。

用 rewrite 指令实现静态资源版本的平滑过渡,核心在于**不改变用户访问 URL 的前提下,内部重写请求路径到新版资源位置**,从而避免前端代码批量修改、CDN 缓存失效或页面报错。它适用于路径结构调整(如从 /dist/css/ 移至 /css/)、版本目录切换(如 /v1/ → /v2/)等场景,与 try_files 的“回退查找”形成互补:前者是主动改写,后者是被动兜底。
明确 rewrite 触发条件与作用范围
rewrite 必须在能匹配原始请求路径的 location 块或 server 级别中配置,且仅对 URI 路径生效(不处理查询参数)。常见适用情形包括:
- 旧版构建产物统一放在
/dist/下,新版已移至根目录,但 HTML 中仍大量引用/dist/main.js - 历史版本部署在
/static/v1/,新版本发布到/static/v2/,需临时将所有 v1 请求导向 v2 - CDN 或反向代理层需标准化路径前缀(如统一去除
/legacy/)
基础 rewrite 语法与安全重定向控制
基本格式为:rewrite [flag];。关键点在于 flag 的选择:
-
last:内部重写,Nginx 会用新 URI 重新匹配 location,适合路径映射(推荐用于静态资源迁移) -
break:停止当前 location 内后续 rewrite,并不再匹配新 URI,适合简单路径截断 -
redirect或permanent:触发 302/301 重定向——这会暴露路径变更、中断缓存、增加跳转延迟,静态资源平滑过渡中应避免使用
示例:将所有 /dist/ 开头的请求,内部重写为去掉 /dist 前缀的路径
rewrite ^/dist/(.*)$ /$1 last;
}
结合正则提取与动态路径生成
当新旧路径存在结构差异(如哈希文件名、目录层级变化),需用正则捕获关键字段再重组:
- 旧路径:
/static/v1/js/app.a1b2c3.js→ 新路径:/js/app.js(去掉版本号和哈希) - 配置:
rewrite ^/static/v1/(js|css|img)/(.+)\.[a-f0-9]{6,}\.(js|css|png|jpg|gif)$ /$1/$2.$3 last; - 说明:捕获分组
$1(目录类型)、$2(文件名主体)、$3(后缀),拼出干净路径
该方式可适配 Webpack/Rollup 的 contenthash 输出,无需等待前端全部更新引用。
与 try_files 协同构建双保险机制
rewrite 是“主动映射”,但无法保证新版资源 100% 已就位;搭配 try_files 可提供兜底能力:
- 先用 rewrite 将
/static/v1/xxx改写为/assets/xxx - 再在
location /assets/中配置try_files $uri /legacy$uri =404,查不到时回退到旧路径 - 上线初期开启日志记录被 rewrite 或回退的请求,持续收敛未覆盖的路径
这种组合既保障了大部分请求直通新版,又为遗漏资源留出缓冲期,真正实现用户无感、运维可控的平滑过渡。

















