Nginx反向代理之路径替换

在使用nginx进行反向代理时,有时需要使用别名,或者说需要进行路径的替换。听不懂?那直接看下面的需求:

1.代理静态资源

在目录"E:\test\data\upload\20221104"下有一张图片1.jpg,在目录"E:\test\data\temp\20221022"也下有一张图片2.jpg,现需要通过nginx来代理访问资源。

1)需求:通过在浏览器访问http://127.0.0.1/img/upload/20221104/1.jpg 和 http://127.0.0.1/img/temp/20221022/2.jpg 和 访问两张图片

nginx默认是通过配置root来代理静态资源,而刚好上述是通过真实的目录去访问的,故在root上配置路径即可

    server {
        listen       80;
        server_name  127.0.0.1;
        
        location /img/ {
            root  E:/test/data;
            index  index.html index.htm;
        }

    }

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

2)需求:通过在浏览器访问http://127.0.0.1/file/upload/20221104/1.jpg 和 http://127.0.0.1/file/temp/20221022/2.jpg 和 访问两张图片

很明显,在目录中并未有file目录,那么此时就需要设置别名,进行访问

    server {
        listen       80;
        server_name  127.0.0.1;
        
        location /file/ {
            alias  E:/test/data/img/;
            index  index.html index.htm;
        }

    }

需要注意的是,在alias后指定的路径,最后一定要加 "/",否则很有可能会因为location配置不当而出现404.

2.代理动态服务

所谓动态服务也就是后端的各种请求,有时直接使用匹配转发,有时需要处理后转发。

现有一个查询用户信息的接口,地址是http://127.0.0.1:8080/api/user/getById?id=123

1)需求:通过nginx转发,使用http://127.0.0.1/api/user/getById?id=123访问用户查询服务

    server {
        listen       80;
        server_name  127.0.0.1;
        
        location /api/ {
            proxy_pass http://127.0.0.1:8080;
        }

    }

通过原有地址直接准发非常简单。

2)需求:通过nginx转发,使用http://127.0.0.1/test/api/user/getById?id=123访问用户查询服务

    server {
        listen       80;
        server_name  127.0.0.1;
        
        location /test/ {
            proxy_pass http://127.0.0.1:8080/;
        }

    }

这里相当于对请求添加了前缀,但在转发的过程中是没有前缀的,故需要去掉。关键点就是地址后面的 "/".

3.关于斜杆"/"的案例对比

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

1)location、proxy_pass都不加斜杠

location /api {
  proxy_pass http://127.0.0.1:8080;
}

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

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

location /api/ {
  proxy_pass http://127.0.0.1:8080;
}

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

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

location /api {
  proxy_pass http://127.0.0.1:8080/;
}

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

4)location、proxy_pass都加斜杠

location /api/ {
  proxy_pass http://127.0.0.1:8080/;
}

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

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

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"

location /api/ {
   proxy_pass http://127.0.0.1:8080/api;
}

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

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

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/"

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种情况,但有些情况可能是错的,配置时需要谨慎。

posted @ 2022-11-07 09:35  钟小嘿  阅读(10261)  评论(1编辑  收藏  举报