⑭.nginx rewrite

rewrite语法

| Syntax:  | rewrite regex replacement [flag]; |
| -------- | --------------------------------- |
| Default: | —                                 |
| Context: | server, location, if              |

//所有请求转发到/pages/maintain.html
rewrite ^(.*)$  /pages/maintain.html  break;

正则表达式

字符 描述
\ 将后面接着的字符标记为一个特殊字符或者一个原义字符或一个向后引用
^ 匹配输入字符串的起始位置
$ 匹配输入字符串的结束位置
* 匹配前面的字符0次或者多次
+ 匹配前面字符串1次或者多次
匹配前面字符串的0次或者1次
. 匹配除“\n”之外的所有单个字符
\d 匹配数字
重复n次
重复n次或者更多次
[c] 匹配单个字符c
[a-z] 匹配a到z小写字母的任意一个
(pattern) 匹配括号内的pattern
正则表达式中特殊字符
\ 转义字符
rewrite index\.PHP$ /pages/maintain.html break;

()用于匹配括号之间的内容 通过$1$2调用
if ($http_user_agent ~ Chrome) {
   rewrite ^(.*)$ /chrome/$1 break;
}
正则表达式终端测试工具
[root@RainGod ~]# yum install pcre-tools
[root@RainGod ~]# pcretest 
PCRE version 8.32 2012-11-30

  re> /(\d+)\.(\d+)\.(\d+)\.(\d+)/
data> 192.168.1.1
 0: 192.168.1.1
 1: 192
 2: 168
 3: 1
 4: 1
data> 222.173.94.214
 0: 222.173.94.214
 1: 222
 2: 173
 3: 94
 4: 214
data> 

rewrite 最后一项flag参数:

标记符号 说明
last 本条规则匹配完成后继续向下匹配新的location URI规则
break 本条规则匹配完成后终止,不在匹配任何规则
redirect 返回302临时重定向
permanent 返回301永久重定向
break last 对比
nginx配置last
server {
    listen 80;
    server_name wqy.test.com;
    access_log logs/wqy-test-com/access.log;
    location ^~ /aaa {
        rewrite ^/aaa/(.*) /bbb/$1 last;
        root /opt/tmp/wqy/test;
    }
    location ^~ /bbb {
        return 200 "hello world\n";
    }
}

测试结果

#curl -s http://wqy.test.com/aaa/index.html -x 127.0.0.1:80
hello world
#curl -s http://wqy.test.com/bbb/index.html -x 127.0.0.1:80
hello world

url由重写前的http://wqy.test.com/aaa/index.html变为http://wqy.test.com/bbb/index.html,重新进行location匹配后,匹配到第二个location条件,所以请求url得到的响应是hello wold
测试结论
配置rewrite last时,请求跳出当前location,进入server块,重新进行location匹配,超过10次匹配不到报500错误。客户端的url不变

配置rewrite break时

nginx配置

server {
    listen 80;
    server_name wqy.test.com;
    access_log logs/wqy-test-com/access.log;
    location ^~ /aaa {
        rewrite ^/aaa/(.*) /bbb/$1 break;
        root /opt/tmp/wqy/test;
    }
    location ^~ /bbb {
        return 200 "hello world\n";
    }
}

测试结果

#curl -s http://wqy.test.com/aaa/index.html -x 127.0.0.1:80
bbb
#curl -s http://wqy.test.com/bbb/index.html -x 127.0.0.1:80
hello world
url由重写前的http://wqy.test.com/aaa/index.html变为http://wqy.test.com/bbb/index.html,nginx按照重写后的url进行资源匹配,匹配到的资源文件是/opt/tmp/wqy/test/bbb/index.html,所以请求url得到的响应就是/opt/tmp/wqy/test/bbb/index.html文件中的内容:bbb。

测试结论
配置rewrite break时,请求不会跳出当前location,但资源匹配会按照重写后的url进行,如果location里面配置的是proxy_pass到后端,后端服务器收到的请求url也会是重写后的url。客户端的url不变。

redirect permanent
rewrite ^(.*)$ https://${server_name}$1 permanent;  永久跳转  京东   浏览器缓存后不会向服务器发送数据确认请求
rewrite ^(.*)$ https://${server_name}$1 redirect;   临时跳转         浏览器每次请求后都会向服务器发送数据确认请求

常见跳转示例情况测试说明
练习1):用户访问/abc/1.html实际上真实访问是/ccc/bbb/2.html

	#http://www.oldboy.com/abc/1.html ==> http://www.oldboy.com/ccc/bbb/2.html
    第一里程:准备真实的访问路径
    [root@web03 ~]# mkdir /code/ccc/bbb -p
    [root@web03 ~]# echo "ccc_bbb_2" > /code/ccc/bbb/2.html

    第二个里程:Nginx跳转配置
    [root@web03 conf.d]# cat ccbb.conf 
    server {
        listen 80;
        location / {
            root /html/www;
            index index.html;
        }
        location /abc/ {
            rewrite (.*) /ccc/bbb/2.html redirect;
            #return 302 /ccc/bbb/2.html;
        }
    }
    
    第三个里程:重启Nginx服务
    [root@web03 ~]# systemctl restart nginx
练习2):用户访问/2018/ccc/bbb/2.html实际上真实访问是/2014/ccc/bbb/2.html
    #http://www.oldboy.com/2018/ccc/bbb/2.html ==> http://www.oldboy.com/2019/ccc/bbb/2.html

	第一次访问网站:
	http://www.oldboy.com/2018/ccc/bbb/2.html  --> 跳转 
	第二次访问网站:
	http://www.oldboy.com/2019/ccc/bbb/2.html
	
    第一个里程:准备真实的访问路径
    [root@web03 ~]# mkdir /html/www/2019/ccc/bbb -p
    [root@web03 ~]# echo "2019_ccc_bbb_2" > /html/www/2019/ccc/bbb/2.html

    第二个里程:Nginx跳转配置
    [root@web03 conf.d]# cat www.conf 
    server {
        listen 80;
		server_name  www.oldboy.com;
        location / {
            root /html/www;
            index index.html;
        }
        location /2018 {
            rewrite ^/2018/(.*)$ /2019/$1 redirect;    
        }
    }
	
    第三个里程:重启Nginx服务
    [root@web03 ~]# systemctl restart nginx
练习3):用户访问/test目录下任何内容, 实际上真实访问是http://www.oldboy.com
    location /test {
        rewrite (.*) http://www.oldboy.com redirect;
    }
练习4):用户访问course-11-22-33.html实际上真实访问是/course/11/22/33/course_33.html
    #http://www.oldboy.com/course-11-22-33.html ==> http://www.oldboy.com/course/11/22/33/course_33.html  
    
	第一个里程 准备真实的访问路径
    [root@web03 ~]# mkdir /html/www/course/11/22/33/ -p
    [root@web03 ~]# echo "docs.etiantian.org" > /html/www/course/11/22/33/course_33.html

    第二个里程 Nginx跳转配置
    [root@web03 conf.d]# cat www.conf 
    server {
        listen 80;
		server_name  www.oldboy.com;
        root /html/www;
        index index.html;
        location / {
            #灵活rewrite ^/course-(.*)-(.*)-(.*).html$ /course/$1/$2/$3/course_$3.html redirect;
            #固定rewrite ^/course-(.*)  /course/11/22/33/course_33.html redirect;
        }
        
    第三个里程 重启Nginx服务
    [root@web03 ~]# systemctl restart nginx

	例5:将http请求,跳转至https   ???
    server {
            listen 80;
            server_name oldboy.com;
            rewrite ^(.*) https://$server_name$1 redirect;
            #return 302 https://$server_name$request_uri;    ???
    }
    
    server {
        listen 443;
        server_name oldboy.com;
        ssl on;
    }
终极测验:
a 访问oldboy.com/oldboy.jpg  --->  www.oldboy.com/oldboy.jpg   临时
    第一个历程:准备环境
    将oldboy.jpg --- 站点目录
    第二个历程:编写配置文件:
    server {
	  listen      80;
	  server_name www.oldboy.com;
	     root  /html/www;
	     index index.html;
	     rewrite ^/(.*)  http://www.oldboy.com/$1  redirect;
	}

    打破循环问题:
    第一种方式:多个server配置
	server { 
    listen   80;
    server_name  oldboy.com;
    rewrite ^/(.*)  http://www.oldboy.com/$1  redirect;
    }
    server {
    	  listen      80;
    	  server_name www.oldboy.com;
    	  root  /html/www;
    	  index index.html;
    }
	第二种方式:打破循环 if 内置变量 
	server {
	  listen      80;
	  server_name www.oldboy.com;
	     root  /html/www;
	     index index.html;
         if ($host ~ ^oldboy.com) { 
            rewrite ^/(.*)  http://www.oldboy.com/$1  redirect;
         }	
    }
nginx常用内置变量:
$host         		记录请求报文请求主体的host信息     
$server_name        当前用户配置server_name的域名信息
$request_filename   当前请求的文件路径名(带网站的主目录/html/www/images/test.jpg)
$request_uri        当前请求的文件路径名(不带网站的主目录/images/test.jpg)
$scheme             用的协议,比如http或者https

第三个历程:配置DNS解析
10.0.0.7   oldboy.com  www.oldboy.com	
   

b 访问www.etiantian.org      --->  www.oldboy.com   永久	
第一个历程:准备环境
将oldboy.jpg --- 站点目录
第二个历程:编写配置文件:
server {
  listen      80;
  server_name www.oldboy.com;
     root  /html/www;
     index index.html;
     if ($host ~ www.etiantian.org) { 
        rewrite ^/(.*)  http://www.oldboy.com/$1  redirect;
     }
}
第三个历程:主配置文件编写
include /etc/nginx/conf.d/www.conf
include /etc/nginx/conf.d/*.conf;
第四个历程:配置DNS解析
10.0.0.7   oldboy.com  www.oldboy.com www.etiantian.org	
posted @ 2021-04-20 08:52  老夫聊发少年狂88  阅读(68)  评论(0)    收藏  举报