Nginx的proxy_pass url 反向代理的配置
说到 Nginx 就不得不说 Nginx 的反向代理是多么的好用,一个指令 proxy_pass
搞定反向代理,对于接口代理、负载均衡很是实用,但 proxy_pass
指令后面的参数很有讲究。
网上有很多什么绝对路径、相对路径的说法,其实在实际的应用中就分为两种情况:
url 只是 host
这里指不包含 $uri
,如:
http://host
- √https://host
- √http://host:port
- √https://host:port
- √http://host/
- xhttp://host:port/
- x
这时候 location
匹配的完整路径将直接透传给 url ,如:
// 访问: / 后端: / // 访问: /api/xx 后端: /api/xx // 访问: /api/xx?aa 后端: /api/xx?aa location / { proxy_pass http://node:8080; } // 访问: /api/ 后端: /api/ // 访问: /api/xx 后端: /api/xx // 访问: /api/xx?aa 后端: /api/xx?aa // 访问: /api-xx?aa 后端: location /api/ { proxy_pass http://node:8080; } // 访问: /api/ 后端: /api/ // 访问: /api/xx 后端: /api/xx // 访问: /api/xx?aa 后端: /api/xx?aa // 访问: /api-xx?aa 后端: /api-xx?aa location /api { proxy_pass http://node:8080; }
url 包含路径
注意,这里的路径哪怕只是一个 /
也是存在的,如:
http://host
- xhttps//host/
- √http://host:port
- xhttps://host:port/
- √http://host/api
- √http://host/api/
- √
当 proxy_pass url
的 url
包含路径时,匹配时会根据 location
的匹配后的链接透传给 url
,注意匹配后就是这样:
location 规则 | 访问的原始链接 | 匹配之后的路径 |
---|---|---|
location / |
/ |
|
location / |
/a |
a |
location / |
/a/b/c?d |
a/b/c?d |
location /a/ |
/a/ |
|
location /a/ |
/a/b/c?d |
b/c?d |
明白匹配之后的路径后,在 proxy_pass url
包含路径时,将会把匹配之后的路径透传给 url
,如:
// 访问: / 后端: / // 访问: /api/xx 后端: /api/xx // 访问: /api/xx?aa 后端: /api/xx?aa location / { proxy_pass http://node:8080/; } // 访问: /api/ 后端: / // 访问: /api/xx 后端: /xx // 访问: /api/xx?aa 后端: /xx?aa // 访问: /api-xx?aa 未匹配 location /api/ { proxy_pass http://node:8080/; } // 访问: /api 后端: / // 访问: /api/ 后端: // // 访问: /api/xx 后端: //xx // 访问: /api/xx?aa 后端: //xx?aa // 访问: /api-xx?aa 后端: /-xx?aa location /api { proxy_pass http://node:8080/; } // 访问: /api/ 后端: /v1 // 访问: /api/xx 后端: /v1xx // 访问: /api/xx?aa 后端: /v1xx // 访问: /api-xx?aa 未匹配 location /api/ { proxy_pass http://node:8080/v1; } // 访问: /api/ 后端: /v1/ // 访问: /api/xx 后端: /v1/xx // 访问: /api/xx?aa 后端: /v1/xx // 访问: /api-xx?aa 未匹配 location /api/ { proxy_pass http://node:8080/v1/; }
由以上规则可以看出,当 proxy_pass url
中包含路径时,结尾的 /
最好同 location
匹配规则一致。
当 proxy_pass 遇到正则
当 location
以正则形式匹配时,proxy_pass
就不能以 /
结束了,也就是不能包含路径了,比如错误的:
location ~* ^/api/ { proxy_pass http://host/; } location / { if ($uri ~* ^/api/) { proxy_pass http://host/; } }
解决办法就是把链接中的路径去掉。
重写代理链接 - url rewrite
当原始链接(浏览器访问的链接)和代理服务器链接规则不一致时,可以使用 Nginx URL Rewrite 功能去动态的重写,如:
location ~* ^/api/ { rewrite ^/api/(.*) /?path=$1 break; proxy_pass http://node:8080; }
以上请求会把匹配 /api/
的链接重写为 /?path=
的链接透传给 node:8080
服务,有意思的是当使用 rewrite
指令并且生效后,proxy_pass url
链接中的路径会被忽略,如:
// 访问: / 后端: /node/ // 访问: /api 后端: /node/api // 访问: /api/ 后端: /?path= // 访问: /api/a/b/c 后端: /?path=a/b/c location / { rewrite ^/api/(.*) /?path=$1 break; proxy_pass http://node:8080/node/; }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 记一次.NET内存居高不下排查解决与启示