2019年9月

https://distinctplace.com/2017/04/19/nginx-resolver-explained/

如果代理地址不是 URI,而是纯域名或者 IP 地址。此时,NGINX 会将匹配到的完整路径传向代理服务器。

注意,如果反代的地址是域名,那么 NGINX 会在启动时自动去将域名解析为 IP,并且在以后一直使用该 IP 进行反代。

For example:

location /test {
    proxy_pass http://127.0.0.1;
}

example.com/test/path => 127.0.0.1/test/path

当结尾带上/时,NGINX 会被将其识别为 URI。此时,NGINX 在反代的时候会自动将 location 匹配的部分移除掉,再将剩余部分传给代理服务器。

For example:
location /test/ {
    proxy_pass http://127.0.0.1/;
}

example.com/test/path => 127.0.0.1/path;

注意:这里的 127.0.0.1/path = 127.0.0.1/ + (/test/path - /test/)

但是,如果 proxy_pass 中的 URI(比如结尾带/) 使用的是 set $variable 定义的,那么只有 / 会被代理传下去

location /test/ {
    resolver 8.8.8.8;
    # 注意结尾斜杠
    set $upstream_host http://***.amazonaws.com/;
    proxy_pass $upstream_host;
}

example.com/test/path => 127.0.0.1/

这种情况下,正确写法为:

location /test/ {
    resolver 8.8.8.8;
    # 注意结尾没有斜杠
    set $upstream_host http://***.amazonaws.com;
    rewrite ^/test/(.*) /$1 break;
    proxy_pass $upstream_host;
}

example.com/test/path => 127.0.0.1/path;

最后,解决问题,将路径指向指定域名,而域名的 IP 可能会被动时 NGINX 的配置。

location /test {
    resolver 8.8.8.8;
    set $upstream_host http://***.amazonaws.com/sub;
    proxy_pass $upstream_host$request_uri;
}