Nginx 中理解proxy_pass和rewrite的用法

Nginx 6个例子理解proxy_pass和rewrite的用法
一、rewrite描述
rewrite 可以重写path,也可以重写整个url(如果存在协议,默认返回302临时跳转,即使加了 last 和 break 也无效)。

rewrite 共有4种flag:last、break、redirect(302)、permanent(301)。

当location 中存在flag时,不会再执行之后的 rewrite 指令集(包括 rewrite 和 return)。

break 和 last 作用相反,break 中止对其它 location 的规则匹配,last 继续向其它 location 进行规则匹配。

当location中存在 rewrite 时,若要使proxy_pass生效, 须和 break 一起使用,否则proxy_pass将被跳过。

与 rewrite 同时存在时,proxy_pass 中的 path 不会替换。

二、proxy_pass描述
proxy_pass 重写的 url 中包含 path 时,会替换 location 块的匹配规则。
proxy_pass 中不含path时,不会发生替换。
三、举例说明
例1 break标记

server {
listen 9000;
server_name localhost;

location /info {
rewrite ^/.* https://baidu.com permanent;
}

location /break {
rewrite /.* /info break;
proxy_pass http://127.0.0.1:9000;
# 此 return 不会执行
return 200 "ok";
}
}
输入:http://localhost:9000/break

执行过程:首先会匹配到 /break 的 location 块,执行了 rewrite 和 proxy_pass之后,跳过 return(因为有 break),重定向到 http://127.0.0.1:9000/info;然后再次进入 server 块,匹配到 /info 的 location 块,最终重定向到了baidu。

总结:两次进入 server

例2 break命令

server {
listen 9000;
server_name localhost;

location /info {
rewrite ^/.* https://www.baidu.com permanent;
}

location /break {
rewrite /.* /info;
break;
proxy_pass http://127.0.0.1:9000;
# 该 return 不执行
return 200 "ok";
}
}
输入:http://localhost:9000/break

执行过程:首先会匹配到 /break 的 location 块,执行了 rewrite 和 proxy_pass,跳过 return(因为有 break),重定向到 http://127.0.0.1:9000/info;然后,再次进行 server 块,匹配到 /info 的 location 块,最后重定向到了baidu。

注意:proxy_pass 最后不要写成http://127.0.0.1:9000/,应去掉最后的斜杠,而例子(1)的写法可加斜杠,也可不加斜杠。

总结:两次进入 server

例3 last标记

server {
listen 9000;
server_name localhost;

location /info {
rewrite ^/.* https://www.baidu.com permanent;
}

location /break {
rewrite /.* /info last;
# 该 proxy_pass 不执行
proxy_pass http://127.0.0.1:9000;
# 该 return 不执行
return 200 "ok";
}

}
输入:http://localhost:9000/break

执行过程:首先会匹配到 /break 的 location 块,执行了 rewrite,跳过 return 和 proxy_pass(因为有 last,proxy_pass 需要和 break 一起用);然后继续匹配,匹配到 /info 的 location 块,最后重定向到了baidu。

总结:一次进入 server,两次 location 匹配

例4 包含proxy_pass包含path

location /api/ {
proxy_pass http://127.0.0.1/proxy/;
}
访问http://example.com/api/data 会被代理到 http://127.0.0.1/proxy/data

location /api/ {
proxy_pass http://127.0.0.1/proxy;
}
因为包含proxy_pass包含path, 所以发生了替换
http://example.com/api/data 会被代理到 http://127.0.0.1/proxydata

location /api/ {
proxy_pass http://127.0.0.1/;
}
因为包含proxy_pass包含path, 所以发生了替换
http://example.com/api/data 会被代理到 http://127.0.0.1/data

例5 proxy_pass 中不含path

location /api/ {
proxy_pass http://127.0.0.1;
}
proxy_pass 中不含path时,则不会发生替换
http://example.com/api/data 会被代理到 http://127.0.0.1/api/data

例6 proxy_pass与 rewrite 同时存在时

location /api/ {
rewrite /api/(.*) /info/$1 break;
proxy_pass http://127.0.0.1/proxy/;
}
与 rewrite 同时存在时,proxy_pass 中的 path 不会替换,相当于不起作用

posted @   vello  阅读(252)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 从HTTP原因短语缺失研究HTTP/2和HTTP/3的设计差异
· 三行代码完成国际化适配,妙~啊~
点击右上角即可分享
微信分享提示