IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 系统运维 -> Nginx Rewrite && 正则表达式 -> 正文阅读

[系统运维]Nginx Rewrite && 正则表达式


前言

现在 Nginx 已经成为很多公司作为前端反向代理 (proxy pass) 服务器的首选,在实际工作中往往会遇到很多跳转(重写URL)的需求。比如,更换域名后需要保持旧的域名能跳转到新的域名上、某网页发生改变需要跳转到新的页面、网站防盗链等等需求。如果在后端使用的Apache服务器,虽然也能做跳转,规则库也很强大,但是用 Nginx 跳转效率会更高。


一、Nginx Rewrite概述

1.Rewrite 场景

  • 调整用户浏览的 URL,看起来更规范,合乎开发及产品人员的需求。
  • 为了让搜索引擎搜录网站内容及用户体验更好,企业会将动态URL地址伪装成静态地址提供服务。
  • 网址换新域名后,让旧的访问跳转到新的域名上。例如,访问京东的 360buy.com 会跳转到 jd.com。
  • 服务端某些业务调整,比如根据特殊变量、目录、客户端的信息进行 URL 调整等

2.Rewrite 实现

  • Nginx 是通过 ngx_http_rewrite_module 模块支持 url 重写、支持 if 条件判断,但不支持 else 。
  • 该模块需要PCRE 支持,应在编译 Nginx 时指定 PCRE 支持,默认已经安装。根据相关变量重定向和选择不同的配置,从一个location跳转到另一个location,不过这样的循环最多可以执行10次,超过后 Nginx 将返回500错误。
  • 同时,重写模块包含 set 指令,来创建新的变量并设其值,这在有些情景下非常有用的,如记录条件标识、传递参数到其他 location、记录做了什么等等。
  • rewrite 功能就是,使用 Nginx 提供的全局变量或自己设置的变量,结合正则表达式和标志位实现 URL 的重写以及重定向

在这里插入图片描述

3. Rewrite 实际场景

3.1 Nginx 跳转需求的实现方式

  • 使用 rewrite 进行匹配跳转

  • 使用 if 匹配全局变量后跳转

  • 使用 location 匹配再跳转

3.2 rewrite 放在 server{},if{},location{} 段中

  • location 只对域名后边的除去传递参数外的字符串起作用——页面文件的路径

3.3 对域名或参数字符串

  • 使用 if 全局变量匹配
  • 使用 proxy_pass 反向代理

二、Nginx 正则表达式

1. 常见的正则表达式元字符

字符说明
^匹配输入字符串的起始位置
$匹配输入字符串的结束位置
*匹配前面的字符零次或多次
+匹配前面的字符一次或多次
?匹配前面的字符零次或一次
.匹配除”\n”之外的任何单个字符
\将后面接着的字符标记为一个特殊字符或一个原义字符或一个向后引用
\ d匹配纯数字
{n}重复n次
{n,}重复n次或更多次
[c]匹配单个字符c
[a-z]匹配a-z小写字母的任意一个
[a-zA-Z]匹配a-z小写字母或A-Z大写字母的任意一个

2. nginx 与 apache 区别

  • 正则表达式是二者的区别之一
    正则表达式:可以更加精确的匹配需求的字符串/参数/位置等

三、Rewrite 命令详解

1. 语法格式

rewrite <regex> <replacement> [flag];

#<regex>:正则表达式        
#<replacement>:跳转后的内容     
#[flag]rewrite支持的flag标记

2. flag 标记

标记说明
last相当于Apache的[L]标记,表示完成rewrite
break本条规则匹配完成即终止,不再匹配后面的任何规则
redirect返回302临时重定向,浏览器地址会显示跳转后的URL地址,爬虫不会更新url
permanent返回301永久重定向,浏览器地址会显示跳转后的URL地址,爬虫更新url
  • last 和 break 比较
lastbreak
使用场景一般写在 server 和 if 中一般使用在 location 中
URL匹配不终止重写后的 urI 匹配终止重写后的 url 匹配
  • last:url 重写后,马上发起一个新请求,再次进入 server 块,重试 location 匹配,超过10次匹配不到报 500 错误,地址栏不变;
  • break:url重写后,直接使用当前资源,不再使用location余下的语句,完成本次请求,地址栏不变

总的来说:last 和 break 再重定向后,地址栏都不会发生变化,这是他们的相同点。不同点在于 last 会写在 server 和 if中,break 是写在location 中,last 不会终止重写后的 url 匹配,break 会终止重写后的 url 匹配。

四、location 解析

1. location 分类

location = patt {}  [精准匹配]
location patt {}    [一般匹配]
location ~ patt {}  [正则匹配]

2. 正则匹配的常用表达式

标记说明
~执行一个正则匹配,区分大小写
~*执行一个正则匹配,不区分大小写
!~执行一个正则匹配,区分大小写不匹配
!~*执行一个正则匹配,不区分大小写不匹配
^~普通字符匹配,使用前缀匹配,如果匹配成功,则不再匹配其他location
=普通字符精确匹配,也就是完全匹配
@定义一个命名的location,使用在内部定向时

3. location 优先级

  • 相同类型的表达式,字符串长的会优先匹配

  • 按优先级匹配

= 类型
^~ 类型表达式
正则表达式(~~*)类型
常规字符串匹配类型,按前缀匹配
通用匹配(/,如果没有其他匹配,任何请求都会匹配到

4. 优先级示例

-------------------------------------------------------------------------------------------------
location = / {                     
[ configuration A ]
}
#精确匹配,主机名后面不能带任何字符串
-------------------------------------------------------------------------------------------------
location / {                     
[configuration B ]
}
#一般匹配,所有的地址都以/开头,这条规则将匹配到所有请求,但正则表达式和最长字符会优先匹配
------------------------------------------------------------------------------------------------
location /documents/ {            
[ configuration C]
}
#匹配任何以/documents/开头的地址,当后面的正则表达式没有匹配到时,才起作用
------------------------------------------------------------------------------------------------
location ~ /documents/abc {     
[ configuration D ]
}
#匹配任何以/documents/abc开头的地址,当后面正则表达式没有匹配到时,才起作用
------------------------------------------------------------------------------------------------

5. rewrite 和 location 比较

  • 相同点:都能实现跳转
  • 不同点:
    ① rewrite 是在同一域名内更改获取资源的路径
    ② location是对一类路径控制访问或反向代理,还可以 proxy_pass 到其他机器
  • rewrite会写在location里,执行顺序
    ①执行server块里面的rewrite指令
    ②执行location匹配
    ③执行选定的location中的rewrite指令

6. location 优先级规则

① 那么 location 优先级到底是怎么排列的?

  • 匹配某个具体文件
(location = 完整路径)>(location ^~ 完整路径)>(location ~* 完整路径)>(location ~ 完整路径)>(location 完整路径)>(location /
  • 用目录做匹配访问某个文件
(location = 目录)>(location ^~ 目录/>(location ~ 目录)>(location ~* 目录)>(location 目录)(location /

② 文件和目录为什么只会在区不区分大小写上会有变动?

  • 正则表达式的目的是为了尽量精确的去匹配
  • 文件,尽量精确的匹配,不区分的话更容易找到
  • 目录,尽量精确匹配,区分大小写优先级更高,更容易找到

③ 在实际网站使用中,至少要有三个匹配规则定义

-------------------------------------------------------------------------------------------------
#第一个必选规则: 直接匹配网站根,通过域名访问网站首页比较频繁(www.baidu.com/),使用这个会加速处理,比如说官网;
可以是一个静态首页,也可以直接转发给后端应用服务器
location = / {
	root	html ;
	index index.html index.htm;
}
-------------------------------------------------------------------------------------------------
#第二个必选规则:处理静态文件请求,这是nginx作为http服务器的强项;
有两种配置模式,目录匹配或后缀匹配,任选其一或搭配使用
location ^~ /static/ {
	root /webroot/static/ ;
}
location ~* \. (html|gif|jpg|jpeg|png)$ {
	root /webroot/res/ ;
} 
------------------------------------------------------------------------------------------------
#第三个必选规则就是通用规则,比如用来转发带.php、.jsp后缀的动态请求到后端应用服务器,
非静态文件请求就默认是动态请求,即跳转或反向代理
upstream	tomcat_ server {
	192.168.8.135:80
	192.168.8.132:80
location / {
	proxy_ pass http://tomcat_server;
}
------------------------------------------------------------------------------------------------

五、案例解析

1. 基于域名的跳转

公司旧域名 www.gkd.com 因业务需求的变更,需要使用新域名 www.haha.com 代替,但是旧域名不能废除,并且旧域名要可跳转到新的域名上,而且后面的参数保持不变。

  • ① 添加映射,开启 nginx 服务
[root@localhost ~]#systemctl status nginx.service 
● nginx.service - nginx
   Loaded: loaded (/usr/lib/systemd/system/nginx.service; enabled; vendor preset: disabled)
   Active: active (running) since 六 2021-10-09 00:30:45 CST; 3 days ago

[root@localhost ~]#vim /etc/hosts
......
192.168.8.135 www.gkd.com www.haha.com
  • ② 创建日志目录,修改主配置文件
[root@localhost ~]#mkdir -p /var/log/nginx
[root@localhost ~]#vim /usr/local/nginx/conf/nginx.conf
......
server {
listen       80;
server_name  www.gkd.com;                  		 #修改域名
charset utf-8;									 #字符集可选择性修改
access_log  /var/log/nginx/www.gkd.com.log; 	 #开启并对日志保存路径进行修改
location / {									 #在原有的location位置进行插入下面内容
if ($host = 'www.gkd.com'){						 #$host为rewrite全局变量,表示请求主机头字段或主机名
rewrite ^/(.*)$ http://www.haha.com/$1 permanent;
}                    							 #$1为匹配的位置变量,即域名后面的字符串,同时永久跳转
root   html;
index  index.html index.htm;
}
......

[root@localhost ~]#nginx -t
nginx: the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /usr/local/nginx/conf/nginx.conf test is successful
[root@localhost ~]#systemctl restart nginx.service 
  • ③ 使用浏览器进行验证
    在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

  • 我们可以看到此时访问 www.gkd.com 时会自动跳转到 www.haha.com 上进行访问,并且在访问www.gkd.com/1.txt 时在错误页面显示时可以看到域名也发生了变化,变成了www.haha.com/1.txt。

2. 基于 IP 地址访问跳转

由于公司的业务新版本上线,要求所有 IP 访问任何内容都显示一个固定的维护页面,只有公司自己的IP地址 192.168.8.135 才能正常访问。

  • ① 创建维护页面的目录,并添加内容
[root@localhost /usr/local/nginx/html]#mkdir -p /var/www/html
[root@localhost /var/www/html]#vim weihu.html
网站维护中~~~~~~~~~~
  • ② 主配置文件配置
......
server {
listen       80;
server_name  www.gkd.com;
charset utf-8;
access_log  /var/log/nginx/www.gkd.com.log;      #开启并对日志保存路径进行修改
set $rewrite true;								 #设置变量$rewrite,变量值为布尔值为true
if ($remote_addr = "192.168.8.135"){	#当客户端ip为192.168.8.135时,将变量值设为flase,不进行重写
set $rewrite false;
}										#除了合法IP,其他都是非法IP,进行重写跳转到维护页面
if ($rewrite = true){                   #布尔值表达式在不满足false情况下,会匹配满足true的location
rewrite (.+) /weihu.html;				#重写在访问IP后边加入/weihu.html,如192.168.8.135/weihu.html
}
location = /weihu.html {
root /var/www/html;						#页面返回/var/www/html/weihu.html里面的内容
}
location / {
root   html;
index  index.html index.htm;
}
......
  • ③ 检测配置文件语法,重启服务
[root@localhost /usr/local/nginx/html]#nginx -t
nginx: the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /usr/local/nginx/conf/nginx.conf test is successful
[root@localhost /usr/local/nginx/html]#systemctl restart nginx.service 
  • ④ 打开浏览器进行验证

此时用另一台机器进行访问192.168.8.135这个地址,会发现页面进行了跳转,跳转到维护的页面,只有IP地址为192.168.8.135的本机才可正常访问

在这里插入图片描述
在这里插入图片描述

3. 基于旧域名跳转到新域名后面加目录

要求:当访问的域名为 http://bbs.gkd.com/post/1.html 时自动跳转到 http: //www.haha.com/bbs/post/1.html

  • ① 创建一个bbs目录下post的网页文件,并添加内容
[root@localhost /var/www/html]#mkdir -p /usr/local/nginx/html/bbs/post
[root@localhost /var/www/html]#vim /usr/local/nginx/html/bbs/post/1.html
[root@localhost /var/www/html]#cat /usr/local/nginx/html/bbs/post/1.html 
<h1>文档有毒~~~~~~</h1>
[root@localhost /var/www/html]#vim /etc/hosts
192.168.8.135 bbs.gkd.com www.haha.com
  • ② 主配置文件配置
.......
server {
listen       80;
server_name  bbs.gkd.com;								#更改域名					
charset utf-8;
access_log  /var/log/nginx/www.gkd.com-access.log;      #开启并对日志保存路径进行修改
location /post {										#添加location;以post开头匹配
rewrite (.+) http://www.haha.com/bbs$1 permanent;       #$1为位置变量,代表/post
}
location / {
root   html;
index  index.html index.htm;
}
......
  • ③ 检查主配置文件语法并重启服务
[root@localhost /var/www/html]#nginx -t
nginx: the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /usr/local/nginx/conf/nginx.conf test is successful
[root@localhost /var/www/html]#systemctl restart nginx.service 
  • 打开浏览器进行验证

在这里插入图片描述

在这里插入图片描述

可以看到此时域名已经自动跳转到了 http: //www.haha.com/bbs/post/1.html

4. 基于参数匹配(多余)的跳转

要求:访问 http://www.gkd.com/100-(100|200)-100.html 会跳转到 http://www.gkd.com的页面

  • ① 主配置文件配置
[root@localhost /var/www/html]#vim /usr/local/nginx/conf/nginx.conf
......
server {
listen       80;
server_name  www.gkd.com;							#更改域名
charset utf-8;
access_log  /var/log/nginx/www.gkd.com-access.log;  #开启并对日志保存路径进行修改
#设置正则匹配,例如:http://www.gkd.com/100-100-123.html													
if ($request_uri ~ ^/100-(100|200)-(\d+)\.html$){   #$repuest_uri内置变量,表示uri,\d 纯数字
rewrite (.*) http://www.gkd.com permanent;			#设置重写
}
location / {
root   html;
index  index.html index.htm;
}
......
  • ② 检查主配置文件语法并重启服务,配置映射
[root@localhost /var/www/html]#nginx -t
nginx: the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /usr/local/nginx/conf/nginx.conf test is successful
[root@localhost /var/www/html]#systemctl restart nginx.service 
[root@localhost /var/www/html]#vim /etc/hosts
192.168.8.135 www.gkd.com
  • ③ 使用浏览器进行验证
    在这里插入图片描述
    在这里插入图片描述

可以看到访问域名 http://www.gkd.com/100-100-100.html 时直接跳转到了 http://www.gkd.com 的页面
访问 http://www.gkd.com/100-200-100.html 也可跳转

5. 基于目录下所有 php 结尾的文件跳转

要求:访问 http://www.gkd.com/upload/123.php 跳转到首页(常用场景:网站新用户提示需要注册)

  • ① 主配置文件配置
[root@localhost /var/www/html]#vim /usr/local/nginx/conf/nginx.conf
......
server {
listen       80;
server_name  www.gkd.com;
charset utf-8;
access_log  /var/log/nginx/www.gkd.com-access.log;
location ~* /upload/.*\.php$ {         
# ~* 表示正则匹配,不区分大小写,匹配/upload目录下所有以.php结尾的文件
rewrite (.*) http://www.gkd.com permanent;
}
location / {
root   html;
index  index.html index.htm;
}
......


  • ② 检查主配置文件语法并重启服务
[root@localhost /var/www/html]#nginx -t
nginx: the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /usr/local/nginx/conf/nginx.conf test is successful
[root@localhost /var/www/html]#systemctl restart nginx.service 
  • ③ 打开浏览器进行验证

在这里插入图片描述

在这里插入图片描述

可以看到访问 http://www.gkd.com/upload/123.php 会跳转到 http://www.gkd.com 首页

6. 基于最普通一条 url 请求的跳转

要求:访问一个具体的页面,如: http://www.gkd.com/abc/123.html,能跳转到首页

  • ① 主配置文件配置
[root@localhost /var/www/html]#vim /usr/local/nginx/conf/nginx.conf
......
    server {
        listen       80;
        server_name  www.gkd.com;
        charset utf-8;
        access_log  /var/log/nginx/www.gkd.com-access.log;
        location ~* /abc/123.html {                     
                rewrite (.+) http://www.gkd.com permanent;
        }
        location / {
            root   html;
            index  index.html index.htm;
        }

......
  • ② 检查主配置文件语法并重启服务
[root@localhost /var/www/html]#nginx -t
nginx: the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /usr/local/nginx/conf/nginx.conf test is successful
[root@localhost /var/www/html]#systemctl restart nginx.service 
  • ③ 使用浏览器进行验证

在这里插入图片描述
在这里插入图片描述

可以看到访问 http://www.gkd.com/abc/123.html 的时候进行了跳转,跳转到了主页面!

总结

  • 配置跳转的原因:为了让URL看起来更规范、合理;企业会将动态URL地址伪装成静态地址提供服务;网址换新域名后,期望用户可以通过旧的访问跳转到新的域名上;服务端某些业务调整

  • Nginx跳转需求的实现方式:①使用rewrite进行匹配跳转(主要匹配的是具体的路径);②使用if匹配全局变量后跳转,结合布尔值时间true和fales的跳转③使用location匹配再跳转(可以匹配后执行proxy_pass,将请求跳转到其他服务上)

  • nginx 服务基于 http 协议 rewrite 重写 mudule 模块,主从URL重写,其中有一个布尔值:返回值的结果只有true或者false;只支持if单分支语句

  • location 分类:① location = patt{} [精准匹配];② location patt {} [一般匹配];③ location ~ patt {} [正则匹配]

  • location 的匹配优先级为:首先精确匹配,其次是前缀匹配,再其次是按文件中顺序的正则匹配,然后匹配不带任何修饰的前缀匹配 ,最后交给 / 进行通用匹配。


  系统运维 最新文章
配置小型公司网络WLAN基本业务(AC通过三层
如何在交付运维过程中建立风险底线意识,提
快速传输大文件,怎么通过网络传大文件给对
从游戏服务端角度分析移动同步(状态同步)
MySQL使用MyCat实现分库分表
如何用DWDM射频光纤技术实现200公里外的站点
国内顺畅下载k8s.gcr.io的镜像
自动化测试appium
ctfshow ssrf
Linux操作系统学习之实用指令(Centos7/8均
上一篇文章      下一篇文章      查看所有文章
加:2021-10-19 12:18:43  更:2021-10-19 12:20:30 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/15 19:45:55-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码