Nginx proxy_pass与变量 - 完整路径

时间:2015-05-18 16:48:57

标签: nginx proxypass

最初我有这样的想法:

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方法,但将代理目标作为变量来强制重新解析?

1 个答案:

答案 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。