首页 > 系统相关 >nginx高级篇rewrite

nginx高级篇rewrite

时间:2024-03-22 22:24:11浏览次数:21  
标签:61 rewrite 高级 nginx master location root

url重写技术
更改请求的url
http://www.yuchaoit.cn/
自动跳转到
new.yuchaoit.cn


比如早期的京东官网,域名叫做 
360buy.com

企业就进行域名修改。
jd.com


老用户他又不知道你改名了,
360buy.com 看到网页无响应,以为京东挂了。。不用这个网站了,京东跑路了,以后用拼多多吧。。


京东就是用rewrite技术,实现,让旧域名的请求,自动重定向(永久重定向)
到新域名


老客户浏览器发出请求 www.360buy.com 浏览器自动的又发出一个新请求,跳转到新请求域名上 www.jd.com(会发现浏览器的url,也自动更换为了新的域名)


rewrite还有哪些功能,
1.实现URL的永久重定向
(1.整个域名的全部替换 2.比如给http跳转到https)


在你学习rewrite之前,要先掌握它基本的一些逻辑参数,如何用

3.这个功能就得通过ngx_http_rewrite_module 这个模块实现
该模块提供了多个指令功能

break     # 中断配置
if        # 请求判断
set      # 设置变量
return  # 返回值


rewrite  # 对用户请求URL重写
官网
https://nginx.org/en/docs/http/ngx_http_rewrite_module.html

该ngx_http_rewrite_module模块用于使用 PCRE 正则表达式更改请求 URI、返回重定向和条件选择配置。

指令语法(if)

1.if语句,用于条件判断,根据判断结果的不同,执行不同的动作,if写在server{}或者location{}标签里。

if (匹配条件) {
    执行动作
}

匹配规则

if的匹配条件可以是如下任意一种。


1.if语句,用于条件判断,根据判断结果的不同,执行不同的动作,if写在server{}或者location{}标签里。


# 比如针对用户的请求客户端判断,或者针对用户的ip地址判断
# 基于nginx的内置变量就可以提取出这些信息。。
if (匹配条件) {
    执行动作
}

匹配条件
	- nginx内置变量
	- 使用nginx的if提供的条件判断符号,等于不等于,....


server {

    # 客户端完全匹配到
    listen 22555;
    server_name localhost;
    root html;
    charset utf-8;

    location  /test-if {

        # 客户端类型完全匹配到 huawei
        if ($http_user_agent = huawei){

            echo "agent is huawei";
        }

        # 客户端类型区分大小写
        # 你这里的正则符号,就是一个完全的字符 ,区分大小写的字符串
        # Iphone ,你只能传入 Iphone才行
        # 基于正则匹配,你得写入正则符号。
        if ($http_user_agent ~ Iphone) {
            echo "agent is Iphone";
        }

        # 客户端类型不区分大小写
        if ($http_user_agent ~* Chrome) {
            echo "agent is Chrome";
        }

        # 如果请求方法不是GET就提示 ”只能用GET方法,你这个烂玩家“
        if ($request_method != GET) {
            echo "必须是GET方法,你这个烂玩家";
        }

        # 如果是IE浏览器,直接提示 "不支持IE,请下载Chrome浏览器"
        # 不区分大小写的正则匹配
        if ($http_user_agent ~* IE){
            echo "不支持IE,请下载Chrome浏览器";
        }

        # 如果上面没有任何匹配,执行如下语句
        echo  "if规则没有匹配到";
        echo "agent is  >>>>>>     $http_user_agent";
        echo "request_method is  >>>>>>>>  $request_method";
    }

}

测试实际用法

# http默认的请求方式,如浏览器访问,如curl命令访问,都是GET方法,获取资源的意思
[root@master-61 ~]#curl 10.0.0.8:22555/test-if
if规则没有匹配到
agent is  >>>>>>     curl/7.29.0
request_method is  >>>>>>>>  GET

测试完全匹配,基于useragent精确匹配到字符串huawei

[root@master-61 ~]## curl -A 表示传输 user-agent的字符串信息
[root@master-61 ~]#
[root@master-61 ~]#
[root@master-61 ~]#curl 10.0.0.8:22555/test-if
if规则没有匹配到
agent is  >>>>>>     curl/7.29.0
request_method is  >>>>>>>>  GET
[root@master-61 ~]#
[root@master-61 ~]#
[root@master-61 ~]#curl -A 'huawei-mate40' 10.0.0.8:22555/test-if
if规则没有匹配到
agent is  >>>>>>     huawei-mate40
request_method is  >>>>>>>>  GET
[root@master-61 ~]#curl -A 'Huawei' 10.0.0.8:22555/test-if
if规则没有匹配到
agent is  >>>>>>     Huawei
request_method is  >>>>>>>>  GET
[root@master-61 ~]#curl -A 'huawei' 10.0.0.8:22555/test-if
agent is huawei

测试区分大小写的正则匹配
重点就在于
如下表达式,你看懂即可

if ($http_user_agnet ~ 正则表达式 ) {
代码块;
}

[root@master-61 ~]##测试区分大小的 Iphone
[root@master-61 ~]#
[root@master-61 ~]#curl -A 'iphone' 10.0.0.8:22555/test-if
if规则没有匹配到
agent is  >>>>>>     iphone
request_method is  >>>>>>>>  GET
[root@master-61 ~]#
[root@master-61 ~]#
[root@master-61 ~]#curl -A 'Iphone' 10.0.0.8:22555/test-if
agent is Iphone
[root@master-61 ~]#curl -A 'IPhone' 10.0.0.8:22555/test-if
if规则没有匹配到
agent is  >>>>>>     IPhone
request_method is  >>>>>>>>  GET

测试不区分大小写的正则匹配

[root@master-61 ~]#
[root@master-61 ~]#curl -A 'windows xxxxx chrome xxxxx' 10.0.0.8:22555/test-if
agent is Chrome
[root@master-61 ~]#
[root@master-61 ~]#
[root@master-61 ~]#curl -A 'windows xxxxx CHroME xxxxx' 10.0.0.8:22555/test-if
agent is Chrome
[root@master-61 ~]#
[root@master-61 ~]#curl -A 'windows xxxxx CHroMxE xxxxx' 10.0.0.8:22555/test-if
if规则没有匹配到
agent is  >>>>>>     windows xxxxx CHroMxE xxxxx
request_method is  >>>>>>>>  GET
[root@master-61 ~]#
[root@master-61 ~]#
[root@master-61 ~]## 看懂扣 3 不懂 4
[root@master-61 ~]## 不区分大小写的正则匹配

测试指定请求方法

[root@master-61 ~]## 如果你给 10.0.0.8:22555/test-if 发送的请求方式不是GET,就会进入如下的 if条件区域
[root@master-61 ~]#
[root@master-61 ~]#curl -X POST 10.0.0.8:22555/test-if 
必须是GET方法,你这个烂玩家
[root@master-61 ~]#
[root@master-61 ~]#
[root@master-61 ~]#curl -X PUT  10.0.0.8:22555/test-if 
必须是GET方法,你这个烂玩家
[root@master-61 ~]#curl -X DELETE  10.0.0.8:22555/test-if 
必须是GET方法,你这个烂玩家


测试IE浏览器

1.测试方法,基于curl去测
[root@master-61 ~]#curl -A 'windows xxxx   IE11xxxxxx' 10.0.0.8:22555/test-if 
不支持IE,请下载Chrome浏览器


2. 直接使用ie浏览器去测

return指令

return用于返回如状态码
或者重写url
或者响应状态码、以及文本等

return之后的命令不会再执行。


具体return用法

[root@web-9 /etc/nginx/conf.d]#cat return.conf 
server {

    listen 22666;
    server_name _;
    root html;

    # 精确匹配,客户端只访问了网页根目录
    location  = / {
        echo "welcome to chaoge linux course.";
    }

    location /test-return {

            # 客户端完全匹配
            if ($http_user_agent = huawei){
              return 200 "agent is  $http_user_agent \n";
            }

            # 限制必须是GET方法
            if ($request_method != GET){

              return 405 "必须是GET方法!其他方法不允许\n";
            }

            # 如果是IE浏览器,就重定向
            if ($http_user_agent ~* IE){
              return 301 http://yuchaoit.cn/cai.jpg;
            }

                        # 没有if条件匹配到
            return 404 "sorry, nothing ....\n";
     }

        # 默认匹配,如果没有匹配到任意内容,跳转到首页 jd.com就是这个做法
        location / {
      return 301 http://yuchaoit.cn/cai.jpg;
        }

        location /ji {
            return 500 "鸡你太美\n";
        }

}


实践return的执行
精准匹配location

[root@master-61 ~]#
[root@master-61 ~]#curl 10.0.0.8:22666/
welcome to chaoge linux course.

没有匹配到任何location,进入默认的location

并且结合了301的用法

浏览器测试
访问的是 10.0.0.8:22666/xixixixi
但是实现了301永久跳转,url会跟着变化
跳转到了 新url ,。http://yuchaoit.cn/cai.jpg

访问具体的location规则

[root@master-61 ~]#curl -I 10.0.0.8:22666/ji
HTTP/1.1 500 Internal Server Error
Server: nginx/1.19.0
Date: Wed, 25 May 2022 03:08:47 GMT
Content-Type: application/octet-stream
Content-Length: 13
Connection: keep-alive

[root@master-61 ~]#
[root@master-61 ~]#
[root@master-61 ~]#curl -I 10.0.0.8:22666/ji/xixixixixi
HTTP/1.1 500 Internal Server Error
Server: nginx/1.19.0
Date: Wed, 25 May 2022 03:09:05 GMT
Content-Type: application/octet-stream
Content-Length: 13
Connection: keep-alive

[root@master-61 ~]#curl  10.0.0.8:22666/ji/xixixixixi
鸡你太美
[root@master-61 ~]#curl  10.0.0.8:22666/ji/xixixixix/haHAHAH
鸡你太美

基于location匹配的综合用法

[root@master-61 ~]#curl -I  10.0.0.8:22666/test-return/xixixixixixi
HTTP/1.1 405 Not Allowed
Server: nginx/1.19.0
Date: Wed, 25 May 2022 03:12:51 GMT
Content-Type: application/octet-stream
Content-Length: 43
Connection: keep-alive

[root@master-61 ~]#curl   10.0.0.8:22666/test-return/xixixixixixi
sorry, nothing ....
[root@master-61 ~]#
[root@master-61 ~]#
[root@master-61 ~]#
[root@master-61 ~]#
[root@master-61 ~]#
[root@master-61 ~]#curl  -A 'huawei'  10.0.0.8:22666/test-return/xixixixixi
agent is  huawei 
[root@master-61 ~]#curl  -I  -A 'huawei'  10.0.0.8:22666/test-return/xixixixixi 
HTTP/1.1 200 OK
Server: nginx/1.19.0
Date: Wed, 25 May 2022 03:13:42 GMT
Content-Type: application/octet-stream
Content-Length: 18
Connection: keep-alive

[root@master-61 ~]#
[root@master-61 ~]#
[root@master-61 ~]## 看懂这些综合用法的,扣 1 不懂2
[root@master-61 ~]#
[root@master-61 ~]#
[root@master-61 ~]#curl -X POST 10.0.0.8:22666/test-return/xxxxxxxxxxxxxxxxxxx
必须是GET方法!其他方法不允许
[root@master-61 ~]#
[root@master-61 ~]#curl -I  -X POST 10.0.0.8:22666/test-return/xxxxxxxxxxxxxxxxxxx
HTTP/1.1 405 Not Allowed
Server: nginx/1.19.0
Date: Wed, 25 May 2022 03:15:18 GMT
Content-Type: application/octet-stream
Content-Length: 43
Connection: keep-alive

set指令

set就是用于设置一个nginx变量,这个值可以是文本、变量或者其组合。

set可以用于设置server{}  location{}  if{}

set 变量名 变量值;
用于在nginx中设置变量,然后可以在配置文件中调用该变量


# 测试用法如下

server {

    listen 22777;
    server_name _;
    root html;
    
    set $my_url http://yuchaoit.cn/data/cai.jpg;

    location /test-set {
        return 301 $my_url;
    }

}

# 测试执行
访问10.0.0.8:22777/test-set/

break指令

语法

break用于终止所在区域的后续指令,且只针对ngx_http_rewrite_module提供的模块指令;
也就是咱们目前所学的这几个rewrite相关的指令,在break后面不会执行了。

break可以用于
server{}
location{}
if{}

break是专门用于终止,rewrite的其他指令的执行的

rewrite这个url重写模块,支持如下几个关键字
break, if, return, rewrite, and set
这些关键字都可以在server{} location中定义

break的作用是,nginx的代码,执行带break之后,就会停止后续的

if, return, rewrite,  set指令的执行。。

结合rewrite实际用法,来看break的其他用法

准备测试配置文件

server {

        listen 22888;
        server_name _;
        root html;

        location / {

                set $my_website yuchaoit.cn;
                echo "welcome to my website:" $my_website;
                break;

                set $my_name yuchao;
                echo "my name is" $my_name;

        }

}

重点,rewrite实际用法

官网
https://nginx.org/en/docs/http/ngx_http_rewrite_module.html#rewrite


句法:    rewrite regex replacement [flag];
默认:    —
语境:    server, location,if

指令语法

1. rewrite指令可以基于用户的请求url,再通过正则表达式的匹配情况,进行地址重写;
2. rewrite指令可以写多条,按照顺序依次执行;
3. rewrite指令可以根据flag标记进行进一步处理(last、break、redirect、permanent)

flag参数解释

可选flag参数可以是以下之一:

last
停止处理当前的 ngx_http_rewrite_module指令集,向下匹配新的locaiton URI规则;

break
ngx_http_rewrite_module与break指令一样, 停止处理当前的指令集 ;

redirect(公司的域名临时更换)
返回带有 302 代码的临时重定向;
如果替换字符串不以“ http://”、“ https://”或“ $scheme”开头,则使用该字符串;
浏览器将显示跳转后的url地址,且浏览器不会做dns缓存记录;

permanent(公司域名永久更换,老域名还在运行)
返回带有 301 代码的永久重定向。
浏览器会记录跳转后的dns缓存,浏览器显示跳转后的url。

工作应用场景

1.设置redirect、permanent参数,浏览器都会更改为跳转后的url,是由服务器返回新的URL,客户端对这个URL重新发起了请求。

2.设置last和break参数,浏览器依然显示原本的URL,由于服务器内部完成跳转。

3.last和break区别
last在标记完本次规则匹配完成后,对其所在的server{}标签重新发起修改后的URL请求,再次匹配location{}。

break是在本条规则匹配完毕后,终止匹配,不再匹配后面的location{};

查看301的实际用法(permanent)
permanent和301永久重定向

HTTP协议规范里,301是永久重定向、302是临时重定向。

301,域名永久更新,更换域名

laoliulinux.cc  旧域名
↓
linux0224.com   新域名


在rewrite中使用 rewrite /  http://linux0224.com permanent;
自动识别为301状态,永久跳转

旧域名配置文件,基于域名的虚拟主机了,做好域名匹配

[root@web-8 /opt/nginx-1-19-0/conf/extra]#cat laoliu.conf 
server {
    listen 80;
    server_name laoliulinux.cc;
    location / {
        root /laoliu/;
        index index.html;
        # rewrite regex   新域名  参数
        #  rewrite regex(提取域名后面的参数)   新域名  参数
        # 简单的域名跳转用法
        rewrite /  http://linux0224.com permanent;
    }
}

# 创建数据文件
[root@web-8 /opt/nginx-1-19-0/conf/extra]#mkdir /laoliu
[root@web-8 /opt/nginx-1-19-0/conf/extra]#
[root@web-8 /opt/nginx-1-19-0/conf/extra]#echo 'laoliu 666666666 old   domain' > /laoliu/index.html 

新域名配置文件 这个新域名,应该放到新服务器上

[root@web-8 /opt/nginx-1-19-0/conf/extra]#cat linux0224.conf 
server {
    listen 80;
    server_name linux0224.com ;
    location / {
        root /linux0224.com/;
        index index.html;
    }
}



#新网站的数据文件
[root@web-8 /opt/nginx-1-19-0/conf/extra]#mkdir /linux0224.com/
[root@web-8 /opt/nginx-1-19-0/conf/extra]#
[root@web-8 /opt/nginx-1-19-0/conf/extra]#
[root@web-8 /opt/nginx-1-19-0/conf/extra]#echo 'new domain  linux0224.com ' > /linux0224.com/index.html

配置客户端,做好域名解析

windows去测试 hosts文件

10.0.0.8 laoliulinux.cc linux0224.com


302的实际用法(redirect)

302,域名的临时跳转,一般是结合业务的临时修改
临时跳转,一般都是企业内部的活页域名,不是二级域名的修改。

看懂扣1,不懂2


# 基于访问路径的url
# 跳转到3级域名的活动页面的操作
# location,和rewrite的玩法,就很清晰了

www.laoliulinux.cc/phone  旧域名
↓
跳转到3级域名,302也
phone.laoliulinux.cc


# 换这个参数,就是302,临时跳转
rewrite /  http://linux0224.com redirect;

旧网站的虚拟主机

server {
    listen 80;
    server_name www.laoliulinux.cc;
    # 添加匹配的活页url
    # 本次是302参数 redirect
    location /phone {
   		 rewrite / http://phone.laoliulinux.cc redirect;
    }
}

# 让用户去访问 www.laoliulinux.cc/phone
自动跳转到 
http://phone.laoliulinux.cc这个新域名

新的活页页面网站

# 创建配置文件

server {
    listen 80;
    server_name phone.laoliulinux.cc;
    location / {
        root /phone.laoliulinux.cc/;
        index index.html;
    }
}

# 创建测试数据
[root@web-8 /opt/nginx-1-19-0/conf/extra]#
[root@web-8 /opt/nginx-1-19-0/conf/extra]#mkdir /phone.laoliulinux.cc/
[root@web-8 /opt/nginx-1-19-0/conf/extra]#
[root@web-8 /opt/nginx-1-19-0/conf/extra]#echo 'new website  !!!!!!!!!!!  phone.laoliulinux.cc !!!!!welcome you !!' > /phone.laoliulinux.cc/index.html

测试配置文件是否正确

[root@web-8 /opt/nginx-1-19-0/conf/extra]#nginx -t
nginx: the configuration file /opt/nginx-1-19-0/conf/nginx.conf syntax is ok
nginx: configuration file /opt/nginx-1-19-0/conf/nginx.conf test is successful
[root@web-8 /opt/nginx-1-19-0/conf/extra]#nginx -s reload

测试客户端的访问

做好dns解析
10.0.0.8 laoliulinux.cc linux0224.com phone.laoliulinux.cc www.laoliulinux.cc

rewrite中的break和last参数

在虚拟主机中,可以定义多个location来处理多个url,进行多个动作的设置。

www.yuchaoit.cn/home/xxxxxxxxxxxx
www.yuchaoit.cn/movie/xxxxxxxxxxxxxx

多个location之间,可以基于last,break去设置匹配规则,比较高级了。。
知道语法即可。


实际用法(last)

可以从 location {}  >  location {}  > location {}
多次匹配。

访问AAA、重写到BBB、重写到CCC,且是服务器内部跳转。

访问AAA
服务器内部跳转BBB
最后跳转到CCC

配置文件

# 创建测试数据,用于查看url内部跳转效果,以及保持了url的参数

# 1.创建测试数据
mkdir -p /linux0224/
echo 'i am ccc,  how are you ~~~' > /linux0224/hello.html


# 2.配置文件
server {
    listen 30000;
    server_name _;

    #
    location /CCC {
        alias /linux0224/;
    }

    location /BBB {
        rewrite ^/BBB/(.*)$ /CCC/$1 last;
    }

    location /AAA {

        rewrite ^/AAA/(.*)$ /BBB/$1 last;
    }

}

图解跳转关系 ,第一次跳转

第二次跳转,最终的访问效果

测试last的访问形式

break参数

break是在本条规则匹配完毕后,终止匹配,不再匹配后面的location{};

表示中断匹配,访问到AAA资源后,只rewrite跳转一次,终止后续的跳转。

# 创建测试数据,用于查看url内部跳转效果,以及保持了url的参数

配置文件如下

server {
    listen 31000;
    server_name _;

    #
    location /CCC {
        root /www/;
        index index.html;
    }

    location /BBB {
      root /www/;
        index index.html;
        rewrite ^/BBB/(.*)$ /CCC/$1 last;
    }

    location /AAA {
        root /www/;
        index index.html;
        rewrite ^/AAA/(.*)$ /BBB/$1 break;
    }

}

得创建好测试的数据

mkdir -p /www/{AAA,BBB,CCC}
echo 'AAA' > /www/AAA/index.html
echo 'BBB' > /www/BBB/index.html
echo 'CCC' > /www/CCC/index.html


标签:61,rewrite,高级,nginx,master,location,root
From: https://www.cnblogs.com/btcm409181423/p/18090511

相关文章

  • nginx高级访客日志切割
    切割理念(先纯手动的去切割日志,备份日志)给nginx进程发送信号,让nginx重新生成一个新日志文件,这就是一个日志切割根本/var/log/nginx/access.log.bak#1.备份原本日志文件nginxreloadreopen信号#配置文件中定义的日志文件名,是这个2./var/log/nginx/access.log #......
  • 服务器上配置nginx
    如何在Ubuntu20.04上安装Nginx-知乎(zhihu.com)就像是在本机进行下载配置一般,成功后你自己可以通过浏览器输入网址访问,本地环回地址或者连接上互联网后的ip地址(那么处于同一局域网的其他设备也可以访问)。在本机部署tomcat也是同理。那么什么情况下可以让互联网下的其......
  • Nginx配置搭建m3u8格式的视频播放服务
    Nginx配置搭建m3u8格式的视频播放服务 本文采用Nginx+FFmpeg来进行m3u8格式的视频播放服务,解决:nginx如何搭建视频服务器,要求流媒体服务,视频hls分片加载FFmpeg概念介绍FFmpeg是一个开源的计算机程序,可以用来记录、转换、编辑和流化数字音频和视频。FFmpeg的名称来自MPEG视频......
  • 2020-6-22-MySQL高级
    数据库引擎对比、索引、SQL语句的性能分析、优化、其他数据库引擎对比MyISAMInnoDB外键不支持支持事务不支持支持行表锁表锁行锁缓存只缓存索引索引、数据都缓存表空间小大关注点性能事务索引1索引分类单值索引:一个索引只包含单个......
  • APS(Advanced Planning and Scheduling)高级计划和排程系统
    APS是什么?APS系统的主要功能有哪些?数字化转型网小编整理了一份资料,从APS是什么?APS的主要功能是什么?两个角度来讲述APS系统。一、APS是什么?APS(AdvancedPlanningandScheduling)高级计划和排程系统,主要是利用计算机运算速度快,数据存储、传递、演绎、纠错和交换方便,可以把人的很......
  • Nginx+ModSecurity(WAF) 加强 Web 应用程序安全性
    Nginx和ModSecurity加强Web应用程序的安全性在当今互联网时代,Web应用程序的安全性变得尤为重要。为了保护应用程序和用户的数据免受恶意攻击和漏洞利用,使用合适的工具和技术是必不可少的。本文将探讨如何使用两个流行的工具——Nginx和ModSecurity,来加强Web应用程序的......
  • 2024.03.22【文字海报】如何使用文字来展现中文排版的高级感
    上图这行字除了使用英文以外,它还使用了衬线体。衬线体能够体现出字体的复古文艺的感觉;相应的,如果换成了非衬线体,就会体现出一种现代简约的感觉,相同的文字不同的字体能够带给人们不一样的视觉感受。通过这些主体文字的语言,你就能感受到强烈的风格。当主体变成中文时,画面中这个......
  • nginx.conf常用配置
    server{listen9001;//使该服务器块监听在TCP端口9001上listen9000sslhttp2;//使该服务器块在TCP端口9000上监听HTTPS请求,并启用HTTP/2协议。server_namesiyuan.terwergreen.com;//定义该服务器块的服务器名称为siyuan.terwergreen.......
  • django中分页器的使用方法(初、高级版本)
    效果图:方法如下:1.简单版(较繁琐但是直观):1.1定义数据库模型(models.py)中添加表classProductSample(models.Model):#示例商品表id=models.AutoField(db_column='ID',primary_key=True)#Fieldnamemadelowercase.item_id=models.CharField(verbose......
  • Nginx服务
    NGINX服务目录第一章·Nginx简介4·什么是nginx4·正向代理4·反向代理5·负载均衡5·动静分离6第二章·Nginx的安装7·yum方式安装7·源码包方式安装7·测试8第三章·Nginx常用命令9第四章·Nginx的配置文件11·全局块11·events块11·http块......