最初我有这样的想法:
location /some/path/ {
proxy_pass http://other.host/foo/;
}
对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/;
}
但是我发现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;
}
但是这不包括任何查询参数,所以我再次更新
location ~ ^/some/path/(.*) {
resolver 1.2.3.4;
set $proxy_root "other.host/foo"
proxy_pass http://$proxy_root/$1?$args;
}
这种方法有效,但它意味着有一个?在每个目标地址中,只有部分传入请求实际上有一个?查询部分...
我想我可以做一些进一步的字符串操作,但这感觉有点多。是否有一种比我最初更简单的proxy_pass方法,但将代理目标作为变量来强制重新解析?
答案 0 :(得分:0)
代替使用位置匹配器,另一种选择是使用$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;
}
最后,将其余部分连接起来
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;
}
根据http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_pass,为什么会发生这种情况:
在某些情况下,无法替换请求URI的部分 确定
其中一种情况是
在proxy_pass中使用变量时:
location /name/ { proxy_pass http://127.0.0.1$request_uri; }
在这种情况下,如果在指令中指定了URI,它将照原样传递到服务器,从而替换原始请求URI。
在这种情况下,因为您的proxy_pass指令参数中有$ proxy_root。