最初我有一个这样的conf:
location /some/path/ {
proxy_pass http://other.host/foo/;
}
Run Code Online (Sandbox Code Playgroud)
并且请求http://my.domain/some/path/bar将被代理到http://other.host/foo/bar
我开始在 proxy_pass 中使用变量来强制 nginx 重新解析 DNS:
location /some/path/ {
resolver 1.2.3.4;
set $proxy_root "other.host/foo"
proxy_pass http://$proxy_root/;
}
Run Code Online (Sandbox Code Playgroud)
但是我发现 uri 路径的其余部分不再被附加,所以现在请求http://my.domain/some/path/bar将被代理到简单的http://other.host/foo/.
所以我把它改成了正则表达式
location ~ ^/some/path/(.*) {
resolver 1.2.3.4;
set $proxy_root "other.host/foo"
proxy_pass http://$proxy_root/$1;
}
Run Code Online (Sandbox Code Playgroud)
但这不包括任何查询参数,所以我再次更新
location ~ ^/some/path/(.*) {
resolver 1.2.3.4;
set $proxy_root "other.host/foo"
proxy_pass http://$proxy_root/$1?$args;
}
Run Code Online (Sandbox Code Playgroud)
这有点工作,但这意味着有一个 ? 在每个目标地址中,当只有一些传入请求实际上具有 ?query 部分时...
我想我可以做一些进一步的字符串操作,但这感觉有点多。有没有像我最初做的那样更简单的 proxy_pass 方法,但是将代理目标作为变量来强制重新解析?
小智 5
除了使用位置匹配器,另一种选择是使用$request_uri和匹配您要维护的部件。$request_uri包含完整的 URI,包括查询参数 ( http://nginx.org/en/docs/http/ngx_http_core_module.html#var_request_uri )。
由于location块匹配/some/path/,使用正则表达式获得余数:
if ($request_uri ~* "/some/path(/.*$)")
set $path_remainder $1;
}
Run Code Online (Sandbox Code Playgroud)
最后,连接余数:
location /some/path/ {
resolver 1.2.3.4;
set $proxy_root "other.host/foo";
if ($request_uri ~* "/some/path(/.*$)") {
set $path_remainder $1;
}
proxy_pass http://$proxy_root$path_remainder;
}
Run Code Online (Sandbox Code Playgroud)
至于为什么会发生这种情况,根据http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_pass:
在某些情况下,无法确定要替换的请求 URI 部分
其中一个案例是
在 proxy_pass 中使用变量时:
Run Code Online (Sandbox Code Playgroud)location /name/ { proxy_pass http://127.0.0.1$request_uri; }在这种情况下,如果在指令中指定了 URI,它将按原样传递给服务器,替换原始请求 URI。
这是这种情况,因为您的 proxy_pass 指令参数中有 $proxy_root 。
| 归档时间: |
|
| 查看次数: |
6853 次 |
| 最近记录: |