Nginx:Rewrite跳转+正则表达式+6个生产案列!内容过于真实

为什么要跳转

请耐心看完理论

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

Rewrite跳转场景

●可以调整用户浏览的URL,看起来更规范,合乎开发及产品人员的需求。

●为了让搜索引擎搜录网站内容及用户体验更好,企业会将动态URL地址伪装成静态地址提供服务

●网址换新域名后,让旧的访问跳转到新的域名上。例如,访问京东的360buy.com会跳转到jd.com.

●根据特殊变量、目录、客户端的信息进行URL调整等。

Rewrite跳转实现

一定要耐心看啊,都是干货

● Nginx是通过ngx http rewrite module模块支持url重写、支持if条件判断,但不支
持else,另外该模块需要PCRE支持,应在编译Nginx时指定PCRE支持,默认已经安装。

●根据相关变量重定向和选择不同的配置,从一个location跳转到另一个location,不过这样的循环最多可以执行10次,超过后Nginx将返回500错误。

●同时,重写模块包含set指令,来创建新的变量并设其值,这在有些情景下非常有用的,如记录条件标识、传递参数到其他location、记录做了什么等等。

●rewrite功能就是,使用Nginx提供的全局变量或自己设置的变量,结合正则表达式和标志位实现url重写以及重定向。

Rewrite实际场景

我知道你在快速下滑,你好歹看看吧!

● 在实际工作场景, Nginx跳转需求有三种方式可实现。可以直接用rewrite进行匹配跳转,也可以使用if匹配全局变量后跳转

●另外还可以使用location匹配再跳转,所以rewrite只能放在server{}. ifo, location{}段中,例如location 只能对域名后边的除去传递的参数外
的字符串起作用,例如http://www.domain.com/index.php?id=1只对/index.php重写。

●如果想对域名或参数字符串起作用,可以使用if全局变量匹配,也可以使用proxy pass反向代理。

Rewrite语法

这个你一定要看啊,不然后面你案列看不懂怎么办!

Rewrite 命令的语法如下所示

rewrite [flag];
regex: 正则
replacement: 跳转后的内容
flag: rewrite 支持的 flag 标记

flag 标记说明:

last: 相当于 Apache 的[L]标记, 表示完成 rewrite.
break: 本条规则匹配完成即终止, 不再匹配后面的任何规则。
redirect: 返回 302 临时重定向, 浏览器地址会显示跳转后的 URL 地址,爬虫不会更新url (因为是临时).
permanent: 返回 301 永久重定向,浏览器地址栏会显示跳转后的 URL 地址,爬虫更新 url.

●如果后面不跟 flag 标记,那么默认是 302 临时重定向。在实际工作场景中,还有另一种 return 指定。因为 301 和 302 不能简单的只返回状态码,还必须有重定向的 URL, 这就是 return 指令无法返回 301,302 的原因了.

●last 和 break 区别有点难以理解last 一般写在 server 和 if 中,而 break 一般使用在 location 中, last 不终止重写后的url 匹配, 即新的 url 会再从 server 走一遍匹配流程, 而 break 终止重写后的匹配

Nginx正则表达式

●学习Rewrite之前要对正则表达式要很熟悉,举出一些常用的正则表达式元
字符。要深刻理解和学习每个元字符的含义,并且多动手进行实验,在实际生产环境中要结合多个元字符一起使用

●常用的正则表达式元字符

字符 描述
^ 匹配输入字符串的起始位置
$ 匹配输入字符串的结束位置
* 匹配前面的字符零次或多次。如"ol*“能匹配”。“o"及"ol”、“oll”
+ 匹配前面的字符一次或多次。如"ol+“能匹配"ol"及"oll”、 “oll” ,但不能匹配"o"
? 匹配前面的字符零次或一次,例如"do(es)?“能匹配"do"或者"does” , “?” 等效 于 " {0,1}"
. 匹配除"\n" 之外的任何单个字符,若要匹配包括"\n"在内的任意字符,请使用诸如"[.\n]"之类的模式。
\ 将后面接着的字符标记为一个特殊字符或一个原义字符或一个向后引用。如"\n"匹配一个换行符,而"$“则匹配”$"
\d 匹配纯数字
{n} 重复n次
{n,} 重复n次或更多次
[c] 匹配单个字符c [a-z]匹配 a-z 小写字母的任意一个
[a-z,A-Z] 匹配 a-z 小写字母或A-Z大写字母的任意一个

Location分类

location 大致可以分为三类:
location = patt () [精准匹配
location patt () [一般匹配]
location ~ patt ()[正则匹配]

●精准匹配和一般匹配不需要做详细的说明,主要是正则匹配,下面就是正则匹配的一些表达式,需要多加牢记

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

Location优先级

●在Nginx的location和配置中location的顺序没有太大关系。和location表达式的类型有关, 相同类型的表达式, 字符串长的会优先匹配。

●以下是按优先级排列说明:

1.等号类型(=) 的优先级最高。一旦匹配成功,则不再查找其他匹配项。
2.^~类型表达式。一旦匹配成功,则不再查找其他匹配项
3.正则表达式类型(*) 的优先级次之。
4.常规字符串匹配类型。按前缀匹配。
5.通用匹配(/), 如果没有其它匹配, 任何请求都会匹配到。

●从功能看rewrite和location似乎有点像,都能实现跳转,主要区别在于rewrite是在同一域名内更改获取资源的路径,而location是对一类路径做控制访问或反向代理,还可以proxy_pass到其他机器。很多情况下rewrite也会写在location里,它们的执行顺序是:

1.执行 server 块里面的 rewrite 指令
2.执行 location 匹配
3.执行选定的 location 中的 rewrite 指令

不同Location优先级示例

location= /{#精确匹配/,主机名后面不能带任何字符串。[ configuration A]}
location /{#因为所有的地址都以/开头,所以这条规则将匹配到所有请求,但是正和最长字符串会优先匹配。[ configuration B]}
location /documents/{#匹配任何以 /documents/ 开头的地址,匹配符合以后,还要继续往下搜索,只有后面的正则表达式没有匹配到时,这一条才会起作用。[ configuration C]}
location /documents/abc {#匹配任何以/documents/abc开头的地址,匹配符合以后,还要继续往下搜索,只有后面的正则表达式没有匹配到时,这一条才会起作用。[ configuration D]}
location ^~ /images/ {#匹配任何以/images/开头的地址,匹配符合以后,停止往匹配。[configuration E]}
location ~* .(gifIpgIjpeg)$ {#匹配所有以gif, jpg 或 jpeg 结尾的请求, 然而, 所有请求/images/下的图片会被[ configuration E] 处理, 因为^~的优先级更高。[ configuration F]}
location /images/abc {#最长字符匹配到/images/abc,优先级最低[configuration G ]}
location ~/images/abc {#匹配以/images/abc开头的,优先级次之。[configuration H]}
location /images/abc/1.html {#匹配以/images/abc/1.html文件,如果和正则~/images/abc/1.htmL相比,正则优先级更高[ configuration I ]}

location 优先级总结:

1.如果是匹配某个具体文件:
(location = 完整路径) > (location ^~ 完整路径) > (location ~* 完整路径) > (location ~完整路径) > (location完整路径) > (location /)
2.如果是用目录做匹配访问某个文件:
(location = 目录) > (location ^~目录/ > (location ~ 目录) > (location~*目录) > (location 目录) > (location /)

Rewrite6个生产案列

少年,你真的步考虑回过头去看看理论吗?给个面子看看吧

首先搭建环境:

[root@localhost ~]# vi /usr/local/nginx/conf/nginx.conf
  server {
    
    
      listen       80;
      server_name    www.51xit.top;                   ####更改域名

      #charset koi8-r;

      access_log /var/log/nginx/www.51xit.top.access.log ;       ###改访问日志地址

      location / {
    
     
          root html;
          index index.html index.htm;
      }

[root@localhost ~]# mkdir -p /var/log/nginx/
[root@localhost ~]# touch /var/log/nginx/www.51xit.top.access.log

[root@localhost ~]# systemctl restart nginx

去电脑的的C:\Windows\System32\drivers\etc\hosts 添加两个:

20.0.0.26 www.51xit.top
20.0.0.25 www.52xit.top

打开网页www.51xit.top显示正常
在这里插入图片描述
打开网页www.52xit.top显示正常,这里52xit我用的是Apache
在这里插入图片描述

生产案列1

基于域名的跳转,现在公司旧域名www.51xit.top有业务需求有变更,需要使用新
域名www.52xit.top代替,但是旧域名不能废除,需要跳转到新域名上,而且后面的参
数保持不变。

[root@localhost ~]# vi /usr/local/nginx/conf/nginx.conf

    server {
    
    
        listen       80;
        server_name  www.51xit.top;

        charset utf-8;

        #access_log  /usr/local/nginx/logs/www.51xit.top.access.log;

        location / {
    
    
            #root   html;
            #index  index.html index.htm;
                if ($host = 'www.51xit.top') {
    
    
                rewrite ^/(.*)$ http://www.52xit.top/$1 permanent;
                }
        }
    .....     省部分
    }

[root@localhost~# systemctl restart nginx

打开网页测试一下,需要清除历史缓存:访问www.51xit.top

在这里插入图片描述

生产案列2

基于客户端IP访问跳转,例如今天公司业务版本上线, 所有IP访问任何内容都显
示一个固定维护页面,只有公司IP访问正常。

为了方便验证,我开了三台系统:

Linux两台:
20.0.0.26 配置网站用 网页地址www.51xit.top
20.0.0.140 做客户机使用
一台Windows:
20.0.0.1 做客户机使用
##第一步:修改配置文件
[root@localhost ~]# vi /usr/local/nginx/conf/nginx.conf

#####需要添加的配置文件如下####

    server {
    
    
        listen       80;
        server_name  www.51xit.top;

        charset utf-8;

        #access_log  /usr/local/nginx/logs/www.51xit.top.access.log;
        set $rewrite true;
        if ($remote_addr = "20.0.0.1"){
    
    
        set $rewrite false;
        }

        if ($rewrite = true){
    
    
        rewrite (.+) /wh.html;
        }

        location = /wh.html {
    
    
        root /usr/local/nginx/html/;
        }

        location / {
    
    
            root   html;
            index  index.html index.htm;
        }
    .....    省略部分
    }

######命令解析#############

#设置是否合法的IP标识
set $rewrite true; ##·新增·

###判断是否合法的ip###允许20.0.0.1IP正常访问
if ($remote_addr =“20.0.0.1”)
set Srewrite false;

##其余跳转到wh.html页面
rewrite (.+) /wh.html;

##wh.html存放的路径
root /usr/local/nginx/html/:

#第二步:建一个wh网站以便访问

[root@localhost ~]#  echo "网页维护中,请联系管理员">/usr/local/nginx/html/wh.html

[root@localhost html]# systemctl restart nginx
#第三步,验证

#首先用20.0.0.25访问 www.51xit.top
#再用20.0.0.1访问 www.51xit.top
##下面为140的操作
zzt@localhost ~]$ su - root
Password: 
Last login: Tue Sep  8 18:27:19 CST 2020 from 20.0.0.1 on pts/2

[root@localhost ~]# vi /etc/hosts
20.0.0.26 www.51xit.top

网页跳转到维护

再用20.0.0.1主机访问

在这里插入图片描述

生产案列3

基于旧域名跳转到新域名后面加上目录的跳转,例如现在访问的是http://ww.51 xit.top/post/
现在需要将这个域名下面的访问都跳转到http://www.52xit.top/bbs
而且注意保持域名跳转后的参数不变

#第一步,修改配置文件
[root@localhost html]# vi /usr/local/nginx/conf/nginx.conf
    
    server {
    
    
        listen       80;
        server_name  www.51xit.top;

        charset utf-8;

        #access_log  /usr/local/nginx/logs/www.51xit.top.access.log;

        location /post {
    
    
        rewrite (.+) http://www.51xit.top/bbs$1 permanent;
        }

##第二步   验证

#清除浏览器缓存
#浏览器输入www.51xit.top/post

在这里插入图片描述

生产案列4

基于参数匹配的跳转,例如现在访问:
http://www.51xit.top/100-(100I200)-100.html 跳转到http://www.51xit.top页面
咳咳,插一行,作者想点奶茶了,稍等一下
#第一步,修改配置文件
[root@localhost html]# vi /usr/local/nginx/conf/nginx.conf

    server {
    
    
        listen       80;
        server_name  www.51xit.top;

        charset utf-8;

        #access_log  /usr/local/nginx/logs/www.51xit.top.access.log;
        if ($request_uri ~ ^/100-(100|200)-(\d+).html$) {
    
    
        rewrite (.*) http://www.51xit.top permanent;
        }

##添加从if开始
你看看,看不懂了吧,所以回头看看理论呀
这条是通过访问的url判断的
#第二步,验证  需要访问以下4个:

#浏览器输入http://www.51xit.top/100-100-100.html 
#浏览器输入http://www.51xit.top/100-200-100.html
#浏览器输入http://www.51xit.top/100-200-10078789.html
#浏览器输入http://www.51xit.top/100-200-10078789dddd.html

#下面图片按顺序排放

在这里插入图片描述

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

总结:前三个都能跳转,最后一个因为不是纯数字结尾的所以不能跳转

生产案列5

基于目录下所有php结尾的文件跳转,访问http://www.51xit.top/upload/1.php要跳转到首页

#老规矩

[root@localhost htmlj# vi /usr/local/nginx/conf/nginx.conf

    server {
    
    
        listen       80;
        server_name  www.51xit.top;

        charset utf-8;

        #access_log  /usr/local/nginx/logs/www.51xit.top.access.log;

        location ~* /upload/.*\.php$ {
    
    
        rewrite (.+) http://www.51xit.top permanent;
        }
#第二步验证

1、浏览器输入http://www.51xit.top/upload/1.php   
2、浏览器输入http://www.51xit.top/upload/bbs/1.php
3、浏览器输入http://www.51xit.top/upload/index.html

#以下图片按顺序排放

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

生产案列6

基于最普通一条url请求的跳转,访问一个具体的页面跳转到首页

[root@localhost html]# vi /usr/local/nginx/conf/nginx.conf

   server {
    
    
        listen       80;
        server_name  www.51xit.top;

        charset utf-8;

        #access_log  /usr/local/nginx/logs/www.51xit.top.access.log;

        location ~* ^/1/text.html {
    
    
        rewrite (.+) http://www.51xit.top permanent;
        }

###验证

1、浏览器输入http://www.51xit.top/1/test.html
2、浏览器输入http://www.51xit.top/2/test.html
3、浏览器输入http://www.51xit.top/1/test     

#以下图片按顺序排放

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

看看开头的理论吧

猜你喜欢

转载自blog.csdn.net/weixin_48190891/article/details/108532802