分布式 - 服务器Nginx:一小时入门系列之 rewrite 指令

news/2024/10/18 8:25:10/

文章目录

      • 1. rewrite 指令语法
      • 2. rewrite 指令示例
      • 3. 不使用 last 和 break 重写规则
      • 4. 使用 break 重写规则
      • 5. 使用 last 重写规则

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:8080location / {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”加上原始请求的URIrewrite_log on;rewrite ^/profile/upload http://192.168.1.9:8080$request_uri;# 请求转达到 http://localhost:8080location / {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-alivethis 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!";}
}

② 测试:

[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-alivethis is rewrite test! 

③ 查看 rewrite 重写日志:

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 <==

http://www.ppmy.cn/news/1063040.html

相关文章

课程项目设计--spring security--认证管理功能--宿舍管理系统--springboot后端

写在前面&#xff1a; 还要实习&#xff0c;每次时间好少呀&#xff0c;进度会比较慢一点 本文主要实现是用户管理相关功能。 前文项目建立 文章目录 验证码功能验证码配置验证码生成工具类添加依赖功能测试编写controller接口启动项目 security配置拦截器配置验证码拦截器 …

vue3学习源码笔记(小白入门系列)------ 组件是如何渲染成dom挂载到指定位置的?

文章目录 os准备组件如何被挂载到页面上第一步 createApp 做了哪些工作&#xff1f;ensureRendererbaseCreateRenderercreateAppAPImountrenderpatchprocessComponentprocessElement 总结 os 学习一下vue3 源码&#xff0c;顺便记录分享下 使用vitest 插件调试源码 辅助阅读 …

Vue学习之Vue组件的核心概念

组件是什么 vue组件就是一个个独立的小型的ui模块&#xff0c;整个大型的系统就是由一个个小型的UI模块拼接而成的 vue组件就是vue实例&#xff0c;通过new Vue函数来创建的一个vue实例&#xff0c;不同的组件只不过是options的不同&#xff0c;我们基本百分之90的开发工作都…

C# Winfrom通过COM接口访问和控制Excel应用程序,将Excel数据导入DataGridView

1.首先要创建xlsx文件 2.在Com中添加引用 3. 添加命名空间 using ApExcel Microsoft.Office.Interop.Excel; --这样起个名字方面后面写 4.样例 //点击操作excelDataTable dt new DataTable();string fileName "D:\desktop\tmp\test.xlsx";ApExcel.Application exA…

【C语言每日一题】04. 输出保留3位小数的浮点数

题目来源&#xff1a;http://noi.openjudge.cn/ch0101/04/ 01 输出保留3位小数的浮点数 总时间限制: 1000ms 内存限制: 65536kB 问题描述 读入一个单精度浮点数&#xff0c;保留3位小数输出这个浮点数。 输入 只有一行&#xff0c;一个单精度浮点数。 输出 也只有一行&am…

leetcode1475. 商品折扣后的最终价格 【单调栈】

简单题 第一次错误做法 class Solution { public:vector<int> finalPrices(vector<int>& prices) {int n prices.size();stack<int> st;unordered_map<int, int> mp;int i 0;while(i ! prices.size()) {int t prices[i];if (st.empty() || t …

使用CSS的@media screen 规则为不同的屏幕尺寸设置不同的样式(响应式图片布局)

当你想要在不同的屏幕尺寸或设备上应用不同的CSS样式时&#xff0c;可以使用 media 规则&#xff0c;特别是 media screen 规则。这允许你根据不同的屏幕特性&#xff0c;如宽度、高度、方向等&#xff0c;为不同的屏幕尺寸设置不同的样式。 具体来说&#xff0c;media screen…

算法通关村——数论经典问题解析

1. 辗转相除法 主要目的是获取两个数里面的最大公约数。 public int gcd(int a, int b) {int k 0;do {k a % b;a b;b k;} while (k ! 0);return a;}2. 素数和合数 素数的要求是必须大于等于2&#xff0c;并且只能被1和它本身整除。 判断的方法比较简单&#xff0c;就是从…