try_files 负责存在性判断与流向控制,rewrite 负责路径变形与参数构造;二者通过命名 location 解耦协作:try_files 触发降级跳转,rewrite 在命名 location 中完成 URI 改写,配合 error_page 实现多级代理降级。

try_files 本身不执行重写逻辑,也不能直接调用 rewrite 捕获的变量(比如 $1),但它可以和 rewrite 协同工作——关键在于分工:try_files 负责“存在性判断 + 控制流向”,rewrite 负责“路径变形 + 参数构造”,两者通过命名 location 解耦串联。
用 try_files 触发降级分支,rewrite 完成路径/参数改造
当需要根据文件是否存在,决定是否进入某类降级流程(如带版本号的静态资源 fallback、带地域前缀的路由重写),可让 try_files 跳转到命名 location,在其中用 rewrite 处理 URI 变形:
- try_files 检查 /v2/$uri → 存在则返回;不存在则跳 @fallback
- @fallback 中用 rewrite 把 /api/user → /v1/api/user,再 proxy_pass 到旧版服务
- rewrite 使用 break(非 last),避免重复匹配 location,保证只走一次代理
结合 error_page 实现多级代理降级链
单靠 try_files 无法触发 upstream 故障时的 fallback,必须配合 error_page 和 proxy_intercept_errors。典型结构是:
- 主 location 用 try_files 尝试本地缓存文件,失败则跳 @primary
- @primary 中 proxy_pass 主服务,并开启 proxy_intercept_errors on
- 主服务返回 502/503/504 时,由 error_page 502 503 504 = @backup 捕获
- @backup 中可先 rewrite 修改请求头或路径(如加 ?fallback=1),再 proxy_pass 备用服务
rewrite 在降级中做语义化补全
某些降级场景需补充缺失信息,比如前端请求 /img/logo.png,但 v2 目录下实际是 /v2/images/logo.png —— try_files 无法自动拼接目录,这时 rewrite 就派上用场:
- try_files $uri @v2_fallback;
- location @v2_fallback { rewrite ^/(.*)$ /v2/images/$1 break; root /var/www; }
- 后续由 Nginx 自动按新路径查找文件,命中即返回,不命中再进下一级 fallback
注意隔离层级与执行顺序
rewrite 和 try_files 不能混写在同一 location 的同一层级,否则可能绕过存在性检查。正确做法是:
- 所有 rewrite 放在命名 location 内,仅用于内部跳转后的路径修正
- try_files 必须放在常规 location 块开头,作为第一道判断
- 避免在 try_files 后面写 rewrite,Nginx 会忽略(因 try_files 已决定响应或跳转)
- 若需动态构造 fallback 路径,可用 map 预定义变量,再在 rewrite 中引用(如 rewrite ^/(.*)$ /$version/$1 break;)











