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