小葵花妈妈课堂之Nginx Rewirte

Posted 28线不知名云架构师

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了小葵花妈妈课堂之Nginx Rewirte相关的知识,希望对你有一定的参考价值。

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

一、Rewrite的介绍

  和apache等web服务软件一样,rewrite的组要功能是实现RUL地址的重定向。Nginx的rewrite功能需要PCRE软件的支持,即通过perl兼容正则表达式语句进行规则匹配的。默认参数编译nginx就会支持rewrite的模块,但是也必须要PCRE的支持

  rewrite是实现URL重写的关键指令,根据regex(正则表达式)部分内容,重定向到replacement,结尾是flag标记。

二、rewrite在企业里的应用场景

三、nginx rewrite 基础知识

3.1 nginx里常用的正则表达式元字符

3.2 rewrite基本用法

语法:rewrite regex replacement [flag];
PS:
<regex>:匹配正则
<replacement>:跳转后的内容
[flag]:rewrite支持的flag标记


flag标志位:
last : 相当于Apache的[L]标记,表示完成rewrite
break : 停止执行当前虚拟主机的后续rewrite指令集
redirect : 返回302临时重定向,地址栏会显示跳转后的地址
permanent : 返回301永久重定向,地址栏会显示跳转后的地址


last与break的区别:
last:  适用场景,一般写在server和if中
       URL匹配,不终止重写后的url匹配
break: 适用场景,一般使用再location中
       URL匹配, 终止重写后的url、匹配
       

3.3 rewrite执行顺序

①执行server块里面的rewrite指令。
②执行选定的location中的rewrite指令。
③执行选定的location中 if 中的rewrite指令

四、location跳转

4.1 location跳转分类

4.2 location常用的匹配规则

4.3 location匹配优先级

首先精确匹配 =
其次前缀匹配 ^~
##匹配到后不再往下匹配##
其次是按文件中顺序的正则匹配 ~或~*
然后匹配不带任何修饰的前缀匹配
最后是交给 / 通用匹配

示例:

(1)location = / {}
=为精确匹配 / ,主机名后面不能带任何字符串,比如访问 / 和 /data,则 / 匹配,/data 不匹配
再比如 location = /abc,则只匹配/abc ,/abc/或 /abcd不匹配。若 location  /abc,则即匹配/abc 、/abcd/ 同时也匹配 /abc/。

(2)location / {}
因为所有的地址都以 / 开头,所以这条规则将匹配到所有请求 比如访问 / 和 /data, 则 / 匹配, /data 也匹配,
但若后面是正则表达式会和最长字符串优先匹配(最长匹配)

(3)location /documents/ {}
匹配任何以 /documents/ 开头的地址,匹配符合以后,还要继续往下搜索其它 location
只有其它 location后面的正则表达式没有匹配到时,才会采用这一条

(4)location /documents/abc {}
匹配任何以 /documents/abc 开头的地址,匹配符合以后,还要继续往下搜索其它 location
只有其它 location后面的正则表达式没有匹配到时,才会采用这一条

(5)location ^~ /images/ {}
匹配任何以 /images/ 开头的地址,匹配符合以后,停止往下搜索正则,采用这一条

(6)location ~* \\.(gif|jpg|jpeg)$ {}
匹配所有以 gif、jpg或jpeg 结尾的请求
然而,所有请求 /images/ 下的图片会被 location ^~ /images/ 处理,因为 ^~ 的优先级更高,所以到达不了这一条正则

(7)location /images/abc {}
最长字符匹配到 /images/abc,优先级最低,继续往下搜索其它 location,会发现 ^~ 和 ~ 存在

(8)location ~ /images/abc {}
匹配以/images/abc 开头的,优先级次之,只有去掉 location ^~ /images/ 才会采用这一条

(9)location /images/abc/1.html {}
匹配/images/abc/1.html 文件,如果和正则 ~ /images/abc/1.html 相比,正则优先级更高

location优先级总结:

(location =) > (location 完整路径) > (location ^~ 路径) > (location ~,~* 正则顺序) > (location 部分起始路径) > (location /)

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

第一个必选规则

直接匹配网站根,通过域名访问网站首页比较频繁,使用这个会加速处理,比如说官网。
这里是直接转发给后端应用服务器了,也可以是一个静态首页

location = / {
    proxy_pass http://tomcat_server/;
}

第二个必选规则

处理静态文件请求,这是nginx作为http服务器的强项
有两种配置模式,目录匹配或后缀匹配,任选其一或搭配使用

location ^~ /static/ {
    root /webroot/static/;
}

location ~* \\.(html|gif|jpg|jpeg|png|css|js|ico)$ {
    root /webroot/res/;
}

第三个必选规则

比如用来转发带.php、.jsp后缀的动态请求到后端应用服务器
非静态文件请求就默认是动态请求

location / {
    proxy_pass http://tomcat_server;
}

五、具体操作

5.1 基于域名的跳转

[root@server ~]# systemctl stop firewalld
[root@server ~]# systemctl disable firewalld
[root@server ~]# setenforce 0
[root@server ~]# systemctl status firewalld
● firewalld.service - firewalld - dynamic firewall daemon
   Loaded: loaded (/usr/lib/systemd/system/firewalld.service; disabled; vendor preset: enabled)
   Active: inactive (dead)
     Docs: man:firewalld(1)
[root@server ~]# vim /etc/resolv.conf
	nameserver 114.114.114.114
[root@server ~]# 
[root@server ~]# vim /etc/hosts
	192.168.152.130 www.1.com www.2.com

[root@server ~]# mkdir -p /var/log/nginx/
[root@server ~]# vim /usr/local/nginx/conf/nginx.conf
	    #gzip  on;

    server {
        listen       80;
        server_name  www.1.com; 
        #域名修改
        charset utf-8;
        access_log  /var/log/nginx/www.1.com-access.log;
         #取消注释,开启并对日志保存路径进行修改

        location / {
        #在原有location位置添加内容
            if ($host ='www.1.com') {
            rewrite^/(.*)$ http:// www.2.com/$1 permanent;
        }
            root   html;
            index  index.html index.htm;
        }

[root@server ~]# 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@server ~]# 
[root@server ~]# 
[root@server ~]# systemctl restart nginx

访问www.1.com自动跳转www.2.com

5.2 基于IP地址的跳转

[root@server ~]# vim /usr/local/nginx/conf/nginx.conf

    #gzip  on;

    server {
        listen       80;
        server_name  www.1.com;
        charset utf-8;
        access_log  /var/log/nginx/www.1.com-access.log;
        set $rewrite true;
        if ($remote_addr = "192.168.152.130") {
        set $rewrite false;
        }
        if ($rewrite = true){
        rewrite (.+) /weihu.html;
        }
        location = /weihu.html {
        root /var/www/html;
}
        
        location / {
            root   html;
            index  index.html index.htm;
        }
        #error_page  404              /404.html;
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }

    }

[root@server ~]# mkdir -p /var/www/html
[root@server ~]# echo '<h1> this is weihu web! </h1>' > /var/www/html/weihu.html
[root@server ~]# 
[root@server ~]# 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@server ~]# systemctl restart nginx

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

[root@server ~]# mkdir -p /usr/local/nginx/html/bbs/post
[root@server ~]# echo "<h1> this is 1.html </h1>" >> /usr/local/nginx/html/bbs/post/1.html
[root@server ~]# 
[root@server ~]# echo "192.168.152.130 bbs.1.com" >> /etc/hosts
[root@server ~]# vim /etc/hosts

127.0.0.1   localhost server localhost4 localhost4.localdomain4
::1         localhost localhost.localdomain localhost6 localhost6.localdomain6
192.168.152.130 bbs.1.com www.1.com www.2.com

[root@server ~]# vim /usr/local/nginx/conf/nginx.conf

     #gzip  on;

    server {
        listen       80;
        server_name  bbs.1.com;
        charset utf-8;
        access_log  /var/log/nginx/www.1.com-access.log;
        location /post {
        rewrite (.+) http://www.1.com/bbs$1 permanent;
}

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



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

[root@server html]# vim /usr/local/nginx/conf/nginx.conf

   server {
        listen       80;
        server_name  www.1.com;
        charset utf-8;
        access_log  /var/log/nginx/www.1.com-access.log;
        if ($request_uri ~ ^/100-(100|200)-(\\d+)\\.html$) {
        rewrite (.*) http://www.1.com permanent;
        }

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

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

[root@server ~]# vim /usr/local/nginx/conf/nginx.conf

#gzip  on;

    server {
        listen       80;
        server_name  www.1.com;
        charset utf-8;
        access_log  /var/log/nginx/www.1.com-access.log;

        location ~* /upload/.*\\.php$ {
        rewrite (.+) http://www.1.com permanent;
        }

        location / {
            root   html;
            index  index.html index.htm;
        }
[root@server ~]# nginx -t
[root@server ~]# systemctl restart nginx

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

[root@server ~]# vim /usr/local/nginx/conf/nginx.conf

   #gzip  on;

    server {
        listen       80;
        server_name  www.1.com;
        charset utf-8;
        access_log  /var/log/nginx/www.1.com-access.log;

        location ~* /abc/123.html {
        rewrite (.+) http://www.1.com permanent;
        }

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

[root@server ~]# nginx -t
[root@server ~]# systemctl restart nginx

以上是关于小葵花妈妈课堂之Nginx Rewirte的主要内容,如果未能解决你的问题,请参考以下文章

万字长文第三篇:深入讲解python中一大数据结构之元组(叮叮当~小葵花课堂开课啦!)

万字长文第三篇:深入讲解python中一大数据结构之元组(叮叮当~小葵花课堂开课啦!)

热榜!万字长文第二篇:深入讲解python中一大数据结构之字典(叮叮当~小葵花课堂开课啦!)

热榜!万字长文第一篇:深入讲解python中一大数据结构之列表(叮叮当~小葵花课堂开课啦!)

Python课堂点名器,妈妈再也不会担心我被老师点名了

Nginx Rewirte指令