Nginx中proxy_pass支持变量实现动态反代:用$uri保持路径结构,$request_uri透传带参URI,正则捕获组可重写路径;需注意协议不能变量、末尾斜杠敏感、缓存key须包含相关变量。

在 Nginx 中,proxy_pass 支持使用变量(如 $uri、$request_uri、$args 等)构造动态上游地址,这对实现静态资源的智能反代非常关键——比如将 /static/js/app.abc123.js 自动映射到不同 CDN 节点或版本化存储路径,而无需硬编码每条规则。
用 $uri 保持原始路径结构
当后端服务期望接收完整请求路径时(例如静态文件服务器按 URI 直接查找磁盘文件),直接在 proxy_pass 中拼接变量最稳妥:
location /static/ {
proxy_pass https://cdn.example.com$uri;
}
这样 GET /static/css/main.css 会转发为 GET https://cdn.example.com/static/css/main.css。注意:末尾不能加 /,否则 Nginx 会截掉匹配前缀再拼接,导致路径丢失。
用 $request_uri 透传带参数的完整请求
若需保留查询参数(如缓存 busting 的 ?v=20240501 或签名参数),$uri 不含参数,应改用 $request_uri:
location /assets/ {
proxy_pass https://storage.example.com$request_uri;
}
此时 /assets/logo.png?expires=1717200000&sig=abc 会被完整转发,包括问号及之后内容。注意该变量已编码,无需额外处理。
用正则 + 变量重写路径后再反代
对需要路径重写的场景(如把版本号从 URL 提取出来并插入到上游路径中),可结合 rewrite 和捕获变量:
- 匹配
/v2.1.0/js/app.js并转为https://cdn.example.com/2.1.0/js/app.js - 配置示例:
location ~ ^/v(\d+\.\d+\.\d+)/(.+)$ { rewrite ^/v(\d+\.\d+\.\d+)/(.+)$ /$1/$2 break; proxy_pass https://cdn.example.com; } - 更灵活的方式是直接在
proxy_pass中引用捕获组(Nginx 1.17.5+):location ~ ^/v(\d+\.\d+\.\d+)/(.+)$ { proxy_pass https://cdn.example.com/$1/$2; }
避免常见陷阱
以下细节直接影响动态路径是否生效:
-
变量不能出现在
proxy_pass的协议部分:如proxy_pass $scheme://host不被允许,协议必须字面量 -
不支持嵌套变量:如
$upstream_$env无效,需提前用set定义复合变量 -
URI 末尾斜杠敏感:若
proxy_pass值以/结尾,Nginx 会丢弃 location 匹配部分;否则原样拼接 -
缓存与变量兼容性:若启用
proxy_cache,确保 cache key 包含所有影响路径的变量,例如:proxy_cache_key "$scheme$request_method$host$uri$is_args$args";











