原文:Nginx反向代理之路径替换

在使用nginx进行反向代理时,有时需要使用别名,或者说需要进行路径的替换。

代理静态资源

nginx默认是通过配置root来代理静态资源, 通过真实的目录做为路径去访问,在root上配置路径即可。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
    server {
        listen       80;
        server_name  127.0.0.1;
        
        location /img/ {
            root  /data/www;
            index  index.html index.htm;
        }

    }

这里相当于nginx代理到目录data/www下,然后即可访问到/data/www/img目录下的所有文件。其中img也可以配置为在后面不加 “/",为 location /img,此处后面加不加 “/” 效果一样,但为了规范,建议都加。

设置别名访问。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
    server {
        listen       80;
        server_name  127.0.0.1;
        
        location /file/ {
            alias  /data/www/img/;
            index  index.html index.htm;
        }

    }

此时root路径下并没有file目录,在alias后指定的路径,最后一定要加 “/",即可在访问路径中用file替换img

代理动态服务

直接将请求转发到后端服务

1
2
3
4
5
6
7
8
    server {
        listen       80;
        server_name  127.0.0.1;
        
        location /api/ {
            proxy_pass http://127.0.0.1:8080;
        }
    }

用proxy_pass指定后端真实服务,此时/api/请求会转发到8080。

添加转发前缀

1
2
3
4
5
6
7
8
9
    server {
        listen       80;
        server_name  127.0.0.1;
        
        location /test/ {
            proxy_pass http://127.0.0.1:8080/;
        }

    }

和直接路径转发的区别就是,proxy_pass地址后面的 “/",此时请求的路径由原来的/api/变为/test/api/,但在转发的过程中是没有前缀的。

关于斜杆”/“的案例对比

以服务地址http://127.0.0.1:8080/api/user/getById进行说明,访问地址是http://127.0.0.1/api/user/getById。location后斜杆与proxy_pass后斜杆问题如下:

1)location、proxy_pass都不加斜杠

1
2
3
location /api {
  proxy_pass http://127.0.0.1:8080;
}

实际代理地址:http://127.0.0.1:8080/api/user/getById。正确的

2)location加斜杠,proxy_pass不加斜杠

1
2
3
location /api/ {
  proxy_pass http://127.0.0.1:8080;
}

实际代理地址:http://127.0.0.1:8080/api/user/getById。正确的

3)location不加斜杠,proxy_pass加斜杠

1
2
3
location /api {
  proxy_pass http://127.0.0.1:8080/;
}

实际代理地址:http://127.0.0.1:8080//user/getById。错误的,也出现了双斜杠

4)location、proxy_pass都加斜杠

1
2
3
location /api/ {
  proxy_pass http://127.0.0.1:8080/;
}

实际代理地址:http://127.0.0.1:8080/user/getById

5)location不加斜杠,proxy_pass加"api”

1
2
3
location /api {
   proxy_pass http://127.0.0.1:8080/api;
}

实际代理地址:http://127.0.0.1:8080/api/user/getById。正确的

6)location加斜杠,proxy_pass加"api”

1
2
3
location /api/ {
   proxy_pass http://127.0.0.1:8080/api;
}

实际代理地址:http://127.0.0.1:8080/apiuser/getById。错误的,少了一个斜杆

7)location不加斜杠,proxy_pass加"api/”

1
2
location /api {
   proxy_pass http://127.0.0.1:8080/api/;

实际代理地址:http://127.0.0.1:8080/api//user/getById。这种情况会出现双斜杠问题,后端在认证请求时会校验失败。

8)location加斜杠,proxy_pass加"api/”

1
2
3
location /api/ {
   proxy_pass http://127.0.0.1:8080/api/;
}

实际代理地址:http://127.0.0.1:8080/api/user/getById。正确的

可以看出,两者加不加斜杆的区别还是很大的,不同的场景使用不同的配置即可,但我建议要么两者都加斜杆,要么都不加,这样转发的地址一般不会错。

使用一句标准的话来说,总结如下:(与location是否有斜杆关系不大)

第一,若proxy_pass代理地址端口后无任何字符,则转发后地址为:代理地址+访问的uri。例如第1、2种情况

第二,若proxy_pass代理地址端口后有目录(包括”/"),则转发后地址为:代理地址+访问的uri去除location匹配的路径。例如第3-8种情况,但有些情况可能是错的,配置时需要谨慎。

参考