文章目录

  • 前言
  • 一、Nginx Rewrite概述
    • 1.Rewrite 场景
    • 2.Rewrite 实现
    • 3. Rewrite 实际场景
      • 3.1 Nginx 跳转需求的实现方式
      • 3.2 rewrite 放在 server{},if{},location{} 段中
      • 3.3 对域名或参数字符串
  • 二、Nginx 正则表达式
    • 1. 常见的正则表达式元字符
    • 2. nginx 与 apache 区别
  • 三、Rewrite 命令详解
    • 1. 语法格式
    • 2. flag 标记
  • 四、location 解析
    • 1. location 分类
    • 2. 正则匹配的常用表达式
    • 3. location 优先级
    • 4. 优先级示例
    • 5. rewrite 和 location 比较
    • 6. location 优先级规则
  • 五、案例解析
    • 1. 基于域名的跳转
    • 2. 基于 IP 地址访问跳转
    • 3. 基于旧域名跳转到新域名后面加目录
    • 4. 基于参数匹配(多余)的跳转
    • 5. 基于目录下所有 php 结尾的文件跳转
    • 6. 基于最普通一条 url 请求的跳转
  • 总结

前言

现在 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 比较
last break
使用场景 一般写在 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.3.3:80192.168.3.4:80
location / {proxy_ pass http://tomcat_server;
}
------------------------------------------------------------------------------------------------

五、案例解析

1. 基于域名的跳转

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

  • ① 添加映射,开启 nginx 服务
[root@localhost ~]#systemctl status nginx.service
● nginx.service - nginxLoaded: 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.3.3 www.dsj.com www.dlh.com
  • ② 创建日志目录,修改主配置文件
[root@localhost ~]#mkdir -p /var/log/nginx
[root@localhost ~]#vim /usr/local/nginx/conf/nginx.conf
......
server {listen       80;
server_name  www.dsj.com;                        #修改域名
charset utf-8;                                   #字符集可选择性修改
access_log  /var/log/nginx/www.dsj.com.log;      #开启并对日志保存路径进行修改
location / {                                     #在原有的location位置进行插入下面内容
if ($host = 'www.dsj.com'){                       #$host为rewrite全局变量,表示请求主机头字段或主机名
rewrite ^/(.*)$ http://www.dlh.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.dsj.com 时会自动跳转到 www.dlh.com 上进行访问,并且创建一个1.txt再次访问dsj.com

2. 基于 IP 地址访问跳转

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

  • ① 创建维护页面的目录,并添加内容
[root@localhost /usr/local/nginx/html]#mkdir -p /var/www/html
[root@localhost /usr/local/nginx/html]#cd /var/www/html
[root@localhost /var/www/html]#vim weihu.html
dsj
  • ② 主配置文件配置
......
server {listen       80;
server_name  www.dsj.com;
charset utf-8;
access_log  /var/log/nginx/www.dsj.com.log;      #开启并对日志保存路径进行修改
set $rewrite true;                               #设置变量$rewrite,变量值为布尔值为true
if ($remote_addr = "192.168.3.3"){   #当客户端ip为192.168.3.3时,将变量值设为flase,不进行重写
set $rewrite false;
}                                       #除了合法IP,其他都是非法IP,进行重写跳转到维护页面
if ($rewrite = true){                   #布尔值表达式在不满足false情况下,会匹配满足true的location
rewrite (.+) /weihu.html;              #重写在访问IP后边加入/weihu.html,如192.168.3.3/weihu.html
}
location = /weihu.html {root /var/www/html;                     #页面返回/var/www/html/weihu.html里面的内容
}
location / {root   html;
index  index.html index.htm;
}
......
set $rewrite true;                                #设置变量$rewrite,变量值为布尔值为true
if ($remote_addr = "192.168.3.3"){   #当客户端ip为192.168.3.3时,将变量值设为flase,不进行重写
set $rewrite false;
}                                       #除了合法IP,其他都是非法IP,进行重写跳转到维护页面
if ($rewrite = true){                   #布尔值表达式在不满足false情况下,会匹配满足true的location
rewrite (.+) /weihu.html;              #重写在访问IP后边加入/weihu.html,如192.168.3.3/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
  • ④ 打开浏览器进行验证

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

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

要求:当访问的域名为 http://bbs.dsj.com/post/1.html 时自动跳转到 http: //www.djh.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.3.3 bbs.dsj.com www.dlh.com
  • ② 主配置文件配置
[root@localhost /var/www/html]#vim /usr/local/nginx/conf/nginx.conf.......
server {listen       80;
server_name  bbs.dsj.com;                               #更改域名
charset utf-8;
access_log  /var/log/nginx/www.dsj.com-access.log;      #开启并对日志保存路径进行修改
location /post {                                        #添加location;以post开头匹配
rewrite (.+) http://www.dlh.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.dlh.com/bbs/post/1.html

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

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

  • ① 主配置文件配置
[root@localhost /var/www/html]#vim /usr/local/nginx/conf/nginx.conf
......
server {listen       80;
server_name  www.dsj.com;                           #更改域名
charset utf-8;
access_log  /var/log/nginx/www.dsj.com-access.log;  #开启并对日志保存路径进行修改
#设置正则匹配,例如:http://www.dsj.com/100-100-123.html
if ($request_uri ~ ^/100-(100|200)-(\d+)\.html$){   #$repuest_uri内置变量,表示uri,\d 纯数字
rewrite (.*) http://www.dsj.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.3.3 www.dsj.com
  • ③ 使用浏览器进行验证

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

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

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

  • ① 主配置文件配置
[root@localhost /var/www/html]#vim /usr/local/nginx/conf/nginx.conf
......
server {listen       80;
server_name  www.dsj.com;
charset utf-8;
access_log  /var/log/nginx/www.dsj.com-access.log;
location ~* /upload/.*\.php$ {
# ~* 表示正则匹配,不区分大小写,匹配/upload目录下所有以.php结尾的文件
rewrite (.*) http://www.dsj.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.dsj.com/upload/123.php 会跳转到 http://www.dsj.com 首页

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

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

  • ① 主配置文件配置
[root@localhost /var/www/html]#vim /usr/local/nginx/conf/nginx.conf
......server {listen       80;server_name  www.dsj.com;charset utf-8;access_log  /var/log/nginx/www.dsj.com-access.log;location ~* /abc/123.html {                     rewrite (.+) http://www.dsj.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.dsj.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 的匹配优先级为:首先精确匹配,其次是前缀匹配,再其次是按文件中顺序的正则匹配,然后匹配不带任何修饰的前缀匹配 ,最后交给 / 进行通用匹配。


Nginx Rewrite 正则表达式相关推荐

  1. Nginx Rewrite +正则表达式

    目录 前言 一.Nginx Rewrite概述 1. Rewrite 跳转场景 2. Rewrite 跳转实现 3. Rewrite 实际场景 二.Nginx 正则表达式 1. 常见的正则表达式元字符 ...

  2. Nginx Rewrite 和正则表达式

    目录 前言 一.Nginx Rewrite介绍 1. Rewrite 跳转场景 2. Rewrite 跳转实现 3.Nginx跳转需求的实现方式 4.nginx rewrite中的正则表达式 5.re ...

  3. nginx rewrite 参数和例子

    nginx rewrite 参数和例子 推荐参考地址: Mailing list ARChives 官方讨论区 http://marc.info/?l=nginx Nginx 常见应用技术指南[Ngi ...

  4. Nginx Rewrite详解

    Nginx Rewrite详解 引用链接:http://blog.cafeneko.info/2010/10/nginx_rewrite_note/ 原文如下: 在新主机的迁移过程中,最大的困难就是W ...

  5. Nginx Rewrite规则初探

    Nginx  rewrite(nginx url地址重写) Rewrite 主要的功能就是实现URL的重写,Nginx的Rewrite规则采用Pcre,perl兼容正则表达式的语法规则匹配,如果需要N ...

  6. Nginx系列二:(Nginx Rewrite 规则、Nginx 防盗链、Nginx 动静分离、Nginx+keepalived 实现高可用)...

    一.Nginx Rewrite 规则 1. Nginx rewrite规则 Rewrite规则含义就是某个URL重写成特定的URL(类似于Redirect),从某种意义上说为了美观或者对搜索引擎友好, ...

  7. nginx rewrite php参数,Nginx rewrite伪静态配置参数详解

    nginx rewrite 伪静态配置参数和使用例子(附正则使用说明) 正则表达式匹配,其中: * ~ 为区分大小写匹配 * ~* 为不区分大小写匹配 * !~和!~*分别为区分大小写不匹配及不区分大 ...

  8. nginx rewrite php参数,Nginx泛域名解析及Rewrite重定向普通页面及带参数的页面

    静态地址重定向到带参数的动态地址 rewrite "^(.*)/service/(.*)\.html$" $1/service.php?sid=$2 permanent; 带参数的 ...

  9. Nginx的正则表达式

    Nginx (engine x) 是一个高性能的HTTP和反向代理服务,也是一个IMAP/POP3/SMTP服务.Nginx是由伊戈尔·赛索耶夫为俄罗斯访问量第二的Rambler.ru站点(俄文:Ра ...

最新文章

  1. 0与1c语言编译,C语言程序设计(07776-1)第11章编译预处理课案.ppt
  2. Oracle数据库密码过期重置
  3. python退出程序-【转】python 退出程序的方式
  4. 在IIS6上部署WebService
  5. 大数据盘点00后求职选择,过半职场新人会因工作太简单辞职?
  6. opencv学习笔记5:感兴趣区域ROI
  7. 梳理项目的pom文件
  8. [EasyHexo 专栏] #1 - Markdown 编辑器推荐与语法简介
  9. 无需公式或代码,用生活实例谈谈 AI 自动控制技术“强化学习”算法框架
  10. 甘肃暴雨强度公式_最新给排水计算软件,16大功能常用公式自动计算,配11套施工方案...
  11. 移动智能终端安全防护 笔记
  12. 不停机与停机更新_Kubernetes的零停机滚动更新
  13. 11月合资SUV销量:日系车统治榜单 大众产品攻势“拳意渐乱”
  14. 支气管炎如何治疗,试试这些食疗方,马上见效!
  15. C#(Csharp)基础教程(上)(菜鸟教程笔记)
  16. JPA基础知识----JPA 基本注解,JPA API
  17. Scrapy vs BeautifulSoup
  18. es拼音分词 大帅哥_SpringBoot集成Elasticsearch 进阶,实现中文、拼音分词,繁简体转换...
  19. Elasticsearch索引安装使用
  20. Java实训项目一一拼图游戏(附源码)

热门文章

  1. 软件的壳和壳的含义、概念以及加壳和脱壳方法
  2. 数据结构之---非递归中序遍历二叉树
  3. ImaTest3.4报错failed to find mex-file on path uigetfiles.dll
  4. NLP:数据增强/Data Argumentation【词汇替换、随机Mask、回译、添加噪声】
  5. PS4怪物猎人世界服务器稳定吗,PS4怪物猎人世界冰原掉线怎么办 掉线解决办法亲测有效...
  6. 百度发春节搜索大数据:80后最关注什么?
  7. JSF,为什么把简单的事情复杂化?
  8. PDU和SDU的区别
  9. 图像搜索引擎,图像检索
  10. Android应用socket即时通讯的实现