实现静态目录扁平化重定向的关键是使用 location ^~ /static/v1/ { rewrite ^/static/v1/(.+)$ /$1 last; } 进行内部路径重写,确保浏览器地址栏不变、不触发跳转、CDN缓存有效,且资源由后续 location 真实服务。

实现静态目录扁平化重定向的关键,是让旧路径(如 /static/v1/css/app.css)在用户无感的前提下,自动指向新路径(如 /css/app.css),既不改变浏览器地址栏,也不触发跳转,同时保障资源可访问、CDN 缓存不中断。
明确目标:扁平化 ≠ 重定向
“扁平化”指去除多层嵌套目录(如 /static/v1/、/dist/、/assets/),将资源统一落到更简洁的路径层级(如 /js/、/img/)。这属于内部路径映射,不是 301/302 跳转。用 rewrite ... last; 实现,而非 permanent 或 redirect。
- 错误做法:用
rewrite ^/static/v1/(.*)$ /$1 permanent;→ 浏览器地址栏会变,CDN 缓存失效,SEO 可能受损 - 正确做法:在匹配
/static/v1/的 location 中,用last内部重写,让 Nginx 重新用新 URI 匹配后续 location
精准配置 location + rewrite 组合
推荐使用 ^~ 前缀锁定前缀匹配,避免正则 location 干扰;再在其中用 rewrite 提取并重组路径:
location ^~ /static/v1/ {
rewrite ^/static/v1/(.+)$ /$1 last;
}
这样,请求 /static/v1/js/main.js 会被内部重写为 /js/main.js,然后由 location /js/ 或 location / 下的 root 或 alias 指令真实服务。
- 若新版资源已放在根目录下,确保
root /var/www/html;或等效配置生效 - 若新版资源在子目录(如
/opt/app/build/),可用alias /opt/app/build/;配合 rewrite 使用 - 务必测试重写后路径是否真实存在——建议搭配
try_files $uri =404;做兜底
兼顾多版本共存与灰度切换
上线初期常需保留旧路径可访问性,或按 User-Agent、IP 等条件分流。此时可结合 map 或 if 做条件判断:
map $http_user_agent $use_v2 {
~*curl 0;
default 1;
}
<p>server {
location ^~ /static/ {
if ($use_v2) {
rewrite ^/static/v1/(.+)$ /$1 last;
rewrite ^/static/(.+)$ /$1 last;
}</p><h1>否则走原逻辑,或返回 404</h1><pre class="brush:php;toolbar:false;">}
}
注意:if 在 location 中可用,但不宜嵌套复杂逻辑;高频场景建议用 map 预计算变量,更高效安全。
验证与防踩坑要点
上线前必须验证三件事:是否真重写了、是否服务到了、是否破坏了其他路径。
- 用
curl -I http://yoursite/static/v1/css/style.css查看响应头:状态码应为 200,Location头不应出现(有则说明误用了 redirect) - 临时加
add_header X-Rewritten-URI "$request_uri";,对比原始请求与最终处理 URI - 检查日志中是否有大量
open() "/path/to/xxx" failed (2: No such file),说明重写后路径找不到资源 - 避免循环:确认 rewrite 目标不会再次匹配同一 location(例如不要把
/static/v1/重写成/static/v1/xxx)










