叙述
说到 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/;
}
}