1.rewrite指令
rewrite指令可以定义在server块和location块中,用于URL重写。
rewrite指令的语法:
rewrite regex replacement [flag]
regex为正则表达式部分,用于匹配需要重写的url;replacement为替换内容,将匹配正则表达式的url替换为replacement; flag为可选项目,有4个枚举值:
[1] last : 本条规则匹配完成后,继续向下匹配新的location规则;
[2] break: 本条规则匹配完成即终止,不再匹配后面的任何规则;
[3] redirect : 返回302临时重定向,浏览器地址显示跳转后的URL地址;
[4] permanent : 返回301永久重定向,浏览器地址显示跳转后的URL地址;
2.使用案例
本章节中将通过案例介绍rewrite指令的用法以及4个flag值的作用和区别。
2.1 重写url地址
server {
server_name localhost;
listen 8001;
rewrite ^/query/.*$ /ask/info;
location /ask/info {
return 200 "result from /ask/info";
}
}
测试结果如下所示:
[root@124 html]# curl http://localhost:8001/query/info
result from /ask/info
其中: rewrite ^/query/.*$ /ask/info;
表示将以/query/开头的url替换为/ask/info.
此时,可用正则表达式的分组对上述rewrite指令稍作修改:
rewrite ^/query/(.*)$ /ask/$1;
此时,表示将所有以/query/开头的url中的query替换为ask.
2.2 重定向:redirect 和permanent
server {
server_name localhost;
listen 8001;
rewrite ^/query/.*$ /ask/info redirect;
location /ask/info {
return 200 "result from /ask/info";
}
}
测试结果如下所示:
[root@124 ~]# curl -I http://localhost:8001/ask
HTTP/1.1 302 Moved Temporarily
Server: nginx/1.26.0
Date: Tue, 16 Jul 2024 11:37:41 GMT
Content-Type: text/html
Content-Length: 145
Location: http://localhost:8001/ask/info
Connection: keep-alive
修改为: rewrite ^/query/.*$ /ask/info permanent ;
测试结果如下所示:
[root@124 ~]# curl -I http://localhost:8001/ask
HTTP/1.1 301 Moved Permanently
Server: nginx/1.26.0
Date: Tue, 16 Jul 2024 11:41:48 GMT
Content-Type: text/html
Content-Length: 169
Location: http://localhost:8001/ask/info
Connection: keep-alive
即redirect和permanent 的区别仅在于状态码,一个是302一个是301.
2.3 未添加flag:
server {
server_name localhost;
listen 8001;
rewrite ^/ask(.*)$ /ask1/info;
rewrite ^/ask(.*)$ /ask2/info;
rewrite ^/ask(.*)$ /ask3/info;
location /ask1/info {
return 200 "result from /ask1/info";
}
location /ask2/info {
return 200 "result from /ask2/info";
}
location /ask3/info {
return 200 "result from /ask3/info";
}
}
测试结果如下所示:
[root@124 html]# curl http://localhost:8001/ask
result from /ask3/info
测试结果表明3条rewrite依次被执行了,即未添加flage场景,rewrite指令不会发生中断。
2.4 last和break中断rewrite匹配
server {
server_name localhost;
listen 8001;
rewrite ^/ask(.*)$ /ask1/info last;
rewrite ^/ask(.*)$ /ask2/info;
rewrite ^/ask(.*)$ /ask3/info;
location /ask1/info {
return 200 "result from /ask1/info";
}
location /ask2/info {
return 200 "result from /ask2/info";
}
location /ask3/info {
return 200 "result from /ask3/info";
}
}
测试结果如下:
[root@124 install]# curl http://localhost:8001/ask
result from /ask1/info
将rewrite ^/ask(.*)$ /ask1/info last
修改为 rewrite ^/ask(.*)$ /ask1/info break
后,结果如下:
[root@124 logs]# curl http://localhost:8001/ask
result from /ask1/info
即last和break都会中断rewrite指令的继续执行。
2.5 last和break的区别
在location中使用rewrite时:last重写url后,会继续用重写后的值去匹配下面的location;而break重写url后,不会匹配location, 而是使用新的规则,直接发起一次http请求。
server {
server_name localhost;
listen 8001;
location /break {
rewrite ^/break/(.*)$ /ask/$1 break;
}
location /last {
rewrite ^/last/(.*)$ /ask/$1 last;
}
location /ask {
return 200 "result from /ask";
}
}
测试结果如下所示:
[root@124 logs]# curl http://localhost:8001/last/info
result from /ask
[root@124 logs]# curl http://localhost:8001/break/info
<html>
<head><title>404 Not Found</title></head>
<body>
<center><h1>404 Not Found</h1></center>
<hr><center>nginx/1.26.0</center>
</body>
</html>
对应404的error日志显示为:
#0: *54 open() "/usr/local/nginx/html/ask/info" failed (2: No such file or directory), client: 127.0.0.1, server: localhost, request: "GET /break/info HTTP/1.1", host: "localhost:8001"
结果表明,last重写后,会继续匹配location, 而break不再继续匹配location从而转向寻找文件,因找不到对应的/ask/info文件而抛出404.