原文网址:Nginx系列--rewrite的使用_IT利刃出鞘的博客-CSDN博客
简介
本文介绍Nginx中rewrite的使用。
语法
rewrite regex URL [flag];
flag标志位
- last:停止处理rewrite,并对配更改后的 URI 重新进行搜索(再从 server 走一遍匹配流程)。此时对于当前 server 或 location 上下文,不再处理 rewrite 指令。
- break:停止处理rewrite
- last 和 break 的区别:last 重写 url 后,会再从 server 走一遍匹配流程,而 break 终止重写后的匹配
- last 和 break 的相同点:都能停止处理,后面的 rewrite 指令不会再执行。
- redirect:返回包含 302 代码的临时重定向,在替换字符串不以"http://","https://“或”$scheme"开头时使用.
- permanent:返回包含 301 代码的永久重定向。
- permanent 是永久重定向,浏览器会记住它,会一直重定向你设置的地址。可以通过清除浏览器缓存解决。
rewrite 指令只能返回代码 301 或 302。要返回其他代码,需要在 rewrite 指令后面包含 return 指令。
查看rewrite日志
打开日志开关:rewrite_log on; 可以配置到http,server,location和if上下文中。
示例
配置:nginx.conf
location /first {
rewrite_log on;
rewrite /first(.*) /second$1 last;
}
访问
curl test1.com:8080/first/2.txt
日志结果
示例:break和last
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
结果
重定向到了baidu.com
分析
首先,匹配到 /break 的 location 块,执行了 rewrite 和 proxy_pass,跳过 return(因为有 break),重定向到 http://127.0.0.1:9000/info;然后,再次进行 server 块,匹配到 /info 的 location 块,最后重定向到了baidu。
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
结果
重定向到了baidu.com
分析
首先,匹配到 /break 的 location 块,执行了 rewrite,跳过 return 和 proxy_pass(因为有 last,proxy_pass 需要和 break 一起用);然后继续匹配,匹配到 /info 的 location 块,最后重定向到了baidu。
示例:在location的内部和外部
break和last在location外部
基础示例
server{
listen 80;
server_name test.com;
root /data/wwwroot/test.com;
rewrite /1.html /2.html;
rewrite /2.html /3.html;
}
访问:test.com/1.html
结果:浏览器最终重定向到test.com/3.html
分析:请求1.html文件时,会被重定向到2.html,然后被重定向到3.html,最后返回的文件为3.html
例1:rewrite后添加break
server{
listen 80;
server_name test.com;
root /data/wwwroot/test.com;
rewrite /1.html /2.html break;
rewrite /2.html /3.html;
}
访问:test.com/1.html
结果:浏览器最终重定向到test.com/2.html
分析:请求1.html文件时,会被重定向到2.html,遇到break,不再执行下边的rewrite。
例2:break后还有location
server{
listen 80;
server_name test.com;
root /data/wwwroot/test.com;
rewrite /1.html /2.html break;
rewrite /2.html /3.html;
location /2.html {
return 403;
}
}
访问:test.com/1.html
结果:浏览器最终重定向到test.com/2.html
分析:请求1.html文件时,会被重定向到2.html,遇到break,不再执行下边的rewrite。
break和last在location内部
基础示例
server{
listen 80;
server_name test.com;
root /data/wwwroot/test.com;
location / {
rewrite /1.html /2.html;
rewrite /2.html /3.html;
}
location /2.html {
rewrite /2.html /a.html;
}
location /3.html {
rewrite /3.html /b.html;
}
}
访问:test.com/1.html
结果:浏览器最终重定向到test.com/b.html
分析:请求1.html,会经过两次重定向到3.html,3.html又刚好匹配location /3.html{},所以返回b.html。
访问:test.com/2.html
结果:浏览器最终重定向到test.com/a.html
分析:请求2.html,会经过两次重定向到2.html,2.html又刚好匹配location /2.html{},所以返回a.html。
例1:rewrite后添加break
server{
listen 80;
server_name test.com;
root /data/wwwroot/test.com;
location / {
rewrite /1.html /2.html break;
rewrite /2.html /3.html;
}
location /2.html {
rewrite /2.html /a.html;
}
location /3.html {
rewrite /3.html /b.html;
}
}
访问:test.com/1.html
结果:浏览器最终重定向到test.com/2.html
分析:请求1.html文件时,会被重定向到2.html,遇到break,当前location{} 以及后面的location{} 的指令都不再执行。
例2:break后还有location
server{
listen 80;
server_name test.com;
root /data/wwwroot/test.com;
location / {
rewrite /1.html /2.html last;
rewrite /2.html /3.html;
}
location /2.html {
rewrite /2.html /a.html;
}
location /3.html {
rewrite /3.html /b.html;
}
}
访问:test.com/1.html
结果:浏览器最终重定向到test.com/a.html
分析:请求1.html文件时,会被重定向到2.html,遇到break,不再执行下边的rewrite。2.html会再去匹配一次location,匹配到了location /2.html,于是返回了test.com/a.html。