39Nginx的rewrite规则执行逻辑详解
rewrite跳转
rewrite 本质是 “URL 重写与转发规则”,通过预设条件匹配请求 URL,将其修改为新的 URL 后再处理(如转发到后端服务、返回新页面、永久重定向等)
[root@web01 conf.d]# cat rewrite.conf
server {listen 80;server_name test1.com;root /code/test/;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;
}}
Nginx 中 rewrite 规则的执行逻辑确实是:在当前 location 块内按顺序执行完所有 rewrite 规则后,才会根据新的 URI 重新匹配 location 块(除非使用 last 或 break 标记强制中断)
访问1.html -----> b.html
2.html -------> a.html
3.html ----------> b.html
rewrite跳转标记
在 Nginx 中,rewrite 指令可以通过添加跳转标记(flag) 控制规则执行后的行为,常用的标记有 last、break、redirect、permanent 四种,作用如下:
| 标记 | 作用说明 | 客户端感知性 | 典型使用场景 | 关键特性 |
|---|---|---|---|---|
last | 执行当前规则后,终止当前 location 内后续 rewrite 规则,重新匹配 location | 无感知(内部跳转) | URI 改写后需要匹配其他 location 块处理(如跨 location 规则联动) | 触发新一轮 location 匹配,适用于服务器内部多阶段 URI 处理 |
break | 执行当前规则后,终止所有 rewrite 处理,不重新匹配 location | 无感知(内部跳转) | URI 改写后直接访问对应资源(无需进一步规则处理) | 终止所有 rewrite 流程,直接使用当前 URI 处理请求(如静态文件返回) |
redirect | 改写 URI 后,返回 302 临时重定向 响应,客户端重新请求新 URI | 有感知(地址栏变化) | 临时跳转(如维护期间临时切换资源路径) | 临时跳转,搜索引擎不更新索引,客户端下次请求仍可能使用原 URI |
permanent | 改写 URI 后,返回 301 永久重定向 响应,客户端永久使用新 URI | 有感知(地址栏变化) | 永久迁移(如域名更换、路径永久调整) | 永久跳转,搜索引擎会更新索引,客户端会缓存新 URI 并直接使用 |
[root@web01 conf.d]# cat rewrite.conf
server {listen 80;server_name test1.com;root /code/test/;location / {rewrite /1.html /2.html break; #last或者breakrewrite /2.html /3.html;
}location /2.html {rewrite /2.html /a.html redirect;
}location /3.html {rewrite /3.html /b.html permanent;
}}
last 含义: 停止向后匹配,重新对2.html发起请求,最后返回a.html
break含义: 停止向后匹配,获取2.html中的内容返回给用户,不会重新发起请求,返回2.html
若用 redirect 把 2.html 跳转到 a.html:每次用户访问 2.html,浏览器都会先问服务器「现在该跳哪?」,服务器返回「跳 a.html」,浏览器才跳转。
若用 permanent 把 3.html 跳转到 b.html:用户第一次访问时,浏览器会收到「永久跳 b.html」的指令,之后再访问 3.html 时,浏览器会直接跳 b.html,根本不会再问服务器。
302源站挂了无法访问,301只要缓存过一次,源站挂了也能访问
rewirte跳转案例
1.资源跳转 用户访问test1.com/abc ----->/code/ccc/bbb/2.html
[root@web01 conf.d]# cat rewrite.conf
server {listen 80;server_name test1.com;root /code/test/;location / {rewrite /1.html /2.html break; #last或者breakrewrite /2.html /3.html;
}location /abc {rewrite ^(.*)$ /ccc/bbb/2.html redirect;#return 302 /ccc/bbb/2.html;
}
}
案例2. 通过后项引用,调用用户输入的路径
[root@web01 conf.d]# cat rewrite.conf
server {listen 80;server_name test1.com;location / {root /code;index index.html;
}location /2018 {rewrite ^/2018/(.*)$ /2014/$1 redirect;
}
}正则表达式:^/2018/(.*)$
^/2018/:匹配以 /2018/ 开头的路径(^ 表示开头,$ 表示结尾)。
(.*):捕获 /2018/ 后面的所有内容(.* 匹配任意字符任意次数,括号表示分组捕获,记为 $1)。
改写目标:/2014/$1
将原路径中的 /2018/ 替换为 /2014/,并拼接上捕获到的 $1(即 /2018/ 后面的内容)。
标记:redirect → 302 临时重定向(客户端每次访问都会向服务器确认跳转目标)。
案例3. 用户访问test1.com/course-11-22-33.html ------>/code/course/11/22/33/course_33.html
[root@web01 conf.d]# cat rewrite.conf
server {listen 80;server_name test1.com;root /code;location /2018 {rewrite ^/2018/(.*)$ /2014/$1 redirect;
}location / {#灵活配法rewrite ^/course-(.*)-(.*)-(.*).html$ /course/$1/$2/$3/course_$3.html redirect;#固定配法#rewrite ^/course-(.*) /course/11/22/33/course_33.html redirect;}
}
统一错误处理
统一错误处理
- 当触发 403(权限拒绝)、404(资源未找到)、500/501/502(服务器错误)时,会跳转到自定义错误 location
@error_test。 @error_test内通过rewrite指令,内部跳转到/404.html(break标记终止后续处理,客户端无感知)。
- 当触发 403(权限拒绝)、404(资源未找到)、500/501/502(服务器错误)时,会跳转到自定义错误 location
[root@web01 conf.d]# cat rewrite.conf
server {listen 80;server_name test1.com;root /code;location /2018 {rewrite ^/2018/(.*)$ /2014/$1 redirect;
}location / {#灵活配法rewrite ^/course-(.*)-(.*)-(.*).html$ /course/$1/$2/$3/course_$3.html redirect;error_page 403 404 500 501 502 503 @error_test;
}location @error_test {rewrite ^(.*)$ /404.html break;
}
}给所有请求加一个固定参数
[root@web01 conf.d]# cat rewrite.conf
server {listen 80;server_name test1.com;# $args为Nginx内置变量请求行的参数set $args "&showoffline=1";location / {
root /code;
index index.html;
}}
通过变量指定返回给用户的页面
[root@web01 conf.d]# cat rewrite.conf
server {listen 80;server_name test1.com;root /code/test;charset utf-8;location / {index index.html;set $ip 0; # 设置变量为0if ($remote_addr = "192.168.154.117"){set $ip 1; # 如果来源IP为117则设置为1}if ($ip = 0){ # 判断如果变量为0 则跳转维护页面rewrite ^(.*)$ /wh.html break;
}
}
}
这是我的个人学习笔记,主要用于记录自己对知识点的理解和梳理。由于目前仍在学习探索阶段,内容中难免存在理解偏差或表述疏漏,恳请各位大佬不吝赐教,多提宝贵意见~ 若有不同看法,欢迎理性交流探讨,感谢包容与指正!
