1. rewrite 指令语法
nginx的rewrite指令用于重写URL,可以将一个URL重写为另一个URL。它的语法如下:
rewrite regex replacement [flag];
其中,regex是一个正则表达式,用于匹配需要重写的URL;replacement是重写后的URL;flag是可选的标志,用于控制重写的行为。flag 的常见取值为 last 和 break,都是用于控制重写规则执行的指令:
① break指令会立即停止当前的rewrite规则,并将处理流程交给下一个指令。也就是说,如果当前规则匹配成功,那么后面的规则将不会再被执行。如果没有匹配成功,则会继续执行后面的规则。
② last指令会停止当前的rewrite规则,并将处理流程交给nginx的下一个阶段。也就是说,如果当前规则匹配成功,那么后面的规则也会被执行。如果没有匹配成功,则会继续执行后面的规则。
需要注意的是,break和last指令的区别在于是否继续执行后面的规则。如果需要停止后面的规则,使用break指令;如果需要继续执行后面的规则,使用last指令。
rewrite 指令会导致请求的重新处理,因此可能会影响性能,因此,应该尽量避免在高并发场景下使用rewrite指令。
2. rewrite 指令示例
① Nginx 配置文件 8002.conf:
server{
listen 8002;
server_name rioyi.tomcat;
# 请求转达到 http://localhost:8080
location / {
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://localhost:8080;
}
# 请求ie页面
location = /html/ie.html {
root /some/path/static;
}
# 请求字体文件
location ^~ /fonts/ {
root /some/path/static;
}
# css|js|png|jpg|gif|ico 页面
location ~ \.(css|js|png|jpg|gif|ico) {
root /some/path/static;
}
}
② 访问 http://192.168.1.9:8002 并登录若依管理系统上传一个图片,在响应中获取上传图片的访问路径:http://192.168.1.9:8002/profile/upload/2023/08/26/Spring3_20230826191911A002.jpg,直接在浏览器访问该图片会报错404,因为请求会去访问 /some/path/static 目录下的文件。
{
"msg": "操作成功",
"fileName": "/profile/upload/2023/08/26/Spring3_20230826191911A002.jpg",
"code": 0,
"newFileName": "Spring3_20230826191911A002.jpg",
"url": "http://192.168.1.9:8002/profile/upload/2023/08/26/Spring3_20230826191911A002.jpg",
"originalFilename": "Spring3.jpg"
}
在浏览器当访问图片 http://192.168.1.9:8002/profile/upload/2023/08/26/Spring3_20230826191911A002.jpg 时报错 404 Not Found,因为访问该jpg文件时会去访问 /some/path/static 目录下的文件,因此报错 404 Not Found。
③ 利用 rewrite 指令将请求URL重写为另一个URL,直接访问服务器图片地址:
server{
listen 8002;
server_name rioyi.tomcat;
# 将所有以“/profile/upload”开头的请求重写为“http://192.168.1.9:8080”加上原始请求的URI
rewrite_log on;
rewrite ^/profile/upload http://192.168.1.9:8080$request_uri;
# 请求转达到 http://localhost:8080
location / {
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://localhost:8080;
}
# 请求ie页面
location = /html/ie.html {
root /some/path/static;
}
# 请求字体文件
location ^~ /fonts/ {
root /some/path/static;
}
# css|js|png|jpg|gif|ico 页面
location ~ \.(css|js|png|jpg|gif|ico) {
root /some/path/static;
}
}
④ 访问 http://192.168.1.9:8002/profile/upload/2023/08/26/Spring3_20230826191911A002.jpg 会重定向到 http://192.168.1.9:8080/profile/upload/2023/08/26/Spring3_20230826191911A002.jpg
3. 不使用 last 和 break 重写规则
① 在 /home/AdminLTE-3.2.0/pages下创建一个1.txt,里面内容是this is a file
server{
listen 8000;
server_name localhost;
rewrite_log on;
location / {
rewrite ^/old/(.*) /new/$1;
rewrite ^/new/(.*) /pages/$1;
root /home/AdminLTE-3.2.0;
index index.html index2.html index3.html;
}
location /pages/1.txt {
return 200 "this is rewrite test!";
}
}
Nginx 服务器配置文件监听本地 8000 端口,配置了 rewrite_log 开启重写日志记录。当请求的URL为 /old/1.txt 时,第一条 rewrite 规则将以 /old/ 开头的请求重写为以 /new/ 开头的请求,第二条 rewrite 规则将以 /new/ 开头的请求重写为以 /pages/ 开头的请求,最后接着匹配以 /pages/1.txt 结尾的请求,使用 return 指令返回状态码 200 和消息体 “this is rewrite test!”
② 访问 http://192.168.1.9:8000/old/1.txt,默认以顺序执行:
[root@nginx-dev conf.d]# curl -i http://192.168.1.9:8000/old/1.txt
HTTP/1.1 200 OK
Server: nginx/1.24.0
Date: Sat, 26 Aug 2023 12:55:50 GMT
Content-Type: text/plain
Content-Length: 21
Connection: keep-alive
this is rewrite test!
③ 查看 rewrite 日志:
==> /var/log/nginx/error.log <==
2023/08/26 20:55:50 [notice] 6214#6214: *209 "^/old/(.*)" matches "/old/1.txt", client: 192.168.1.9, server: localhost, request: "GET /old/1.txt HTTP/1.1", host: "192.168.1.9:8000"
2023/08/26 20:55:50 [notice] 6214#6214: *209 rewritten data: "/new/1.txt", args: "", client: 192.168.1.9, server: localhost, request: "GET /old/1.txt HTTP/1.1", host: "192.168.1.9:8000"
2023/08/26 20:55:50 [notice] 6214#6214: *209 "^/new/(.*)" matches "/new/1.txt", client: 192.168.1.9, server: localhost, request: "GET /old/1.txt HTTP/1.1", host: "192.168.1.9:8000"
2023/08/26 20:55:50 [notice] 6214#6214: *209 rewritten data: "/pages/1.txt", args: "", client: 192.168.1.9, server: localhost, request: "GET /old/1.txt HTTP/1.1", host: "192.168.1.9:8000"
==> /var/log/nginx/access.log <==
4. 使用 break 重写规则
break指令会立即停止当前的rewrite规则,并将处理流程交给下一个指令。也就是说,如果当前规则匹配成功,那么后面的规则将不会再被执行。如果没有匹配成功,则会继续执行后面的规则。
① Nginx 配置文件 8000.conf:
break 指令不执行后续的rewrite规则,以新的/new/1.txt
路径去执行块内的其他指令。
server{
listen 8000;
server_name localhost;
rewrite_log on;
location / {
rewrite ^/old/(.*) /new/$1 break;
rewrite ^/new/(.*) /pages/$1;
root /home/AdminLTE-3.2.0;
index index.html index2.html index3.html;
}
location /pages/1.txt {
return 200 "this is rewrite test!";
}
}
当请求的URL为 /old/1.txt 时,第一条规则将会匹配并将其重写为/new/1.txt,然后使用break关键字终止 rewrite 规则的匹配。 nginx将不再继续匹配后续的rewrite规则,而是直接使用当前规则的重写结果进行请求处理。
② 访问 http://192.168.1.9:8000/old/1.txt :报错 404 Not Found
[root@nginx-dev conf.d]# curl -i http://192.168.1.9:8000/old/1.txt
HTTP/1.1 404 Not Found
Server: nginx/1.24.0
Date: Sat, 26 Aug 2023 13:08:49 GMT
Content-Type: text/html
Content-Length: 153
Connection: keep-alive
<html>
<head><title>404 Not Found</title></head>
<body>
<center><h1>404 Not Found</h1></center>
<hr><center>nginx/1.24.0</center>
</body>
</html>
③ 查看 rewrite 日志:
2023/08/26 21:08:49 [notice] 6283#6283: *210 "^/old/(.*)" matches "/old/1.txt", client: 192.168.1.9, server: localhost, request: "GET /old/1.txt HTTP/1.1", host: "192.168.1.9:8000"
2023/08/26 21:08:49 [notice] 6283#6283: *210 rewritten data: "/new/1.txt", args: "", client: 192.168.1.9, server: localhost, request: "GET /old/1.txt HTTP/1.1", host: "192.168.1.9:8000"
2023/08/26 21:08:49 [error] 6283#6283: *210 open() "/home/AdminLTE-3.2.0/new/1.txt" failed (2: No such file or directory), client: 192.168.1.9, server: localhost, request: "GET /old/1.txt HTTP/1.1", host: "192.168.1.9:8000"
==> /var/log/nginx/access.log <==
5. 使用 last 重写规则
last指令会停止当前的rewrite规则,并将处理流程交给nginx的下一个阶段。也就是说,如果当前规则匹配成功,那么后面的规则也会被执行。如果没有匹配成功,则会继续执行后面的规则。
① Ngiinx 配置文件8000.conf:
server{
listen 8000;
server_name localhost;
rewrite_log on;
location / {
rewrite ^/old/(.*) /new/$1 last;
rewrite ^/new/(.*) /pages/$1;
root /home/AdminLTE-3.2.0;
index index.html index2.html index3.html;
}
location /pages/1.txt {
return 200 "this is rewrite test!";
}
}
② 测试:文章来源:https://www.toymoban.com/news/detail-674718.html
[root@nginx-dev conf.d]# curl -i http://192.168.1.9:8000/old/1.txt
HTTP/1.1 200 OK
Server: nginx/1.24.0
Date: Sat, 26 Aug 2023 13:42:02 GMT
Content-Type: text/plain
Content-Length: 21
Connection: keep-alive
this is rewrite test!
③ 查看 rewrite 重写日志:文章来源地址https://www.toymoban.com/news/detail-674718.html
2023/08/26 21:42:02 [notice] 6346#6346: *211 "^/old/(.*)" matches "/old/1.txt", client: 192.168.1.9, server: localhost, request: "GET /old/1.txt HTTP/1.1", host: "192.168.1.9:8000"
2023/08/26 21:42:02 [notice] 6346#6346: *211 rewritten data: "/new/1.txt", args: "", client: 192.168.1.9, server: localhost, request: "GET /old/1.txt HTTP/1.1", host: "192.168.1.9:8000"
2023/08/26 21:42:02 [notice] 6346#6346: *211 "^/old/(.*)" does not match "/new/1.txt", client: 192.168.1.9, server: localhost, request: "GET /old/1.txt HTTP/1.1", host: "192.168.1.9:8000"
2023/08/26 21:42:02 [notice] 6346#6346: *211 "^/new/(.*)" matches "/new/1.txt", client: 192.168.1.9, server: localhost, request: "GET /old/1.txt HTTP/1.1", host: "192.168.1.9:8000"
2023/08/26 21:42:02 [notice] 6346#6346: *211 rewritten data: "/pages/1.txt", args: "", client: 192.168.1.9, server: localhost, request: "GET /old/1.txt HTTP/1.1", host: "192.168.1.9:8000"
==> /var/log/nginx/access.log <==
到了这里,关于分布式 - 服务器Nginx:一小时入门系列之 rewrite 指令的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!