文章目录
前言
nginx通过ngx_http_rewrite_module模块支持url重写、支持if条件判断,但不支持else(所以if判断语句为单分支)。
另外该模块需要PCRE支持,应在编译nginx时指定PCRE支持。根据相关变量重定向和选择不同的配置,从一个location跳转到另一个location,不过这样的循环最多可以执行10次,超过后nginx将返回500错误。
同时,重写模块包含set指令,来创建新的变量并设其值,这在有些情景下非常有用的,如记录条件标识、传递参数到其他location、记录做了什么等等。
一、Rewrite简介
1.1 Rewrite跳转场景
- URL看起来更加规范、合理
- 企业会将动态URL地址伪装成静态地址提供服务
- 网址更换新域名后,会让旧的访问网址
- 服务端某些业务跳转
1.2 Rewrite跳转实现
1.3 Rewrite实用场景
-
Nginx跳转需求的实现方式有三种
① 使用 rewrite 进行匹配跳转
② 使用 if 匹配全局变量后跳转
③ 使用 location 匹配再跳转
-
rewrite 可以放在 server{},if{}, location{} 段中
rewrite 不能放在 http {} 段中,因为http段中指的是协议
-
对域名或参数字符串
① 使用if全局变量匹配
② 使用 proxy_pass 反向代理
1.4 常用正则表达式元字符
二、Rewrite命令
2.1 rewrite的语法
rewrite <regex> <replacement> [flag];
# 正则 跳转后的内容 rewrite支持的flag标记
2.2 flag标记详解
爬虫:是一种按照一定的规则,自动地抓取万维网信息的程序或者脚本(工具)
正则表达式:处理字符串的工具(按照各种规则进行处理,而正则表达式就是定义规则的工具)
三、location字段
3.1 location 分类
- location = patt {} [精准匹配]
- location patt {} [一般匹配 ]
- location ~ patt {} [正则匹配]
3.1.1 正则匹配的常用表达式
3.2 location 优先级
-
相同类型的表达式,字符串长的会优先匹配
-
按优先级排列如下:
= 类型
^~ 类型表达式
正则表达式 (和*)类型
常规字符串匹配类型,按前缀匹配
通用匹配(/),如果没有其他匹配,任何请求都会匹配到
小结: location中 优先级从高到低 :‘=’ > ‘^~’ > ‘和*’ > 除通用匹配(/)的其他匹配形式 > ‘/’
3.3 比较 rewrite与 location
-
相同点
都能实现跳转
-
不同点
rewrite 是在同一域名内更改获取资源的路径
location是对一类路径做控制访问或反向代理,还可以proxy_pass(反向代理) 到其他服务器
-
rewrite会写在location中,执行顺序
优先执行 server块里面的 rewrite指令
然后执行 location匹配
最后执行选定的 location中的 rewrite指令
3.4 location优先级规则
-
匹配某个具体文件
( location = 完整路径)>( location ^~ 完整路径)>( location ~* 完整路径)>( location ~ 完整路径)>( location完整路径)>( location /)
-
用目录做匹配访问某个文件
( location = 目录)>( location ^~ 目录)>( location ~ 目录)>
( location ~* 目录)>( location 目录)>( location /)
小结:匹配某个具体文件与用目录做匹配访问某个文件区别只有location ~* 与 location ~ 的优先级不同
示例:
location = / { #精确匹配 /,主机名后面不能带任何字符串
[configuraion A ]
}
location / { #所有的地址都以/开头,这条规则将匹配到所有请求,但正则和最长字符串会优先匹配
[configuraion B ]
}
location /documents/ { #匹配任何以/documents/开头的地址,当后面的正则表达式没有匹配到时,才起作用
[configuraion C ]
}
location ~ /documents/abc { #匹配任何以/documents/abc开头的地址,当后面的正则表达式没有匹配到时,才会起作用
[configuraion D ]
}
location ^~ /images/ { #以/images/开头的地址,匹配符合后,停止往下匹配
[configuraion E ]
}
location ~*\.(gif|jpg|gpeg)$ { #匹配所有以 gif, jpg或jpeg结尾的请求, images/下的图片会被 [configuration E]处理,因为^~的优先级更高
[configuraion F ]
}
location /images/abc { #最长字符匹配到 /images/abc,优先级最低
[configuraion G ]
}
location ~ /images/abc { #以/images/abc开头的,优先级次之
[configuraion H ]
}
location /images/abc/1.html { #如果和正则 ~ images/abc/1.htm相比,正则优先级更高
[configuraion I ]
}
四、具体场景及配置(实验部分)
实验环境:
Ⅰ yum安装nginx(或者使用手工编译安装)
Ⅱ 准备两台虚拟机
一台centos7服务器 (IP地址为192.168.181.140)
一台win10主机 (IP地址为192.168.181.136)
4.1 场景一:基于域名的跳转
-
公司旧域名www.shuita.com,因业务需求有变更,需要使用新域名www.newshuita.com代替
条件一:不能废除旧域名
条件二:从旧域名跳转到新域名,且保持其参数不变
4.1.1 加载Nginx官方源
- ① 下载Nginx官方源
[root@localhost ~]# rpm -Uvh http://nginx.org/packages/centos/7/noarch/RPMS/nginx-release-centos-7-0.el7.ngx.noarch.rpm
引入Nginx官方源,实际上下载的是RPM包,下载后会自动加载到yum仓库中,加载后才可以使用yum 安装Nginx
- ② 查看Nginx配置文件所在目录
[root@localhost ~]# rpm -qc nginx
/etc/logrotate.d/nginx
/etc/nginx/conf.d/default.conf #Nginx主配置文件
/etc/nginx/fastcgi_params
/etc/nginx/koi-utf
/etc/nginx/koi-win
/etc/nginx/mime.types
/etc/nginx/nginx.conf
/etc/nginx/scgi_params
/etc/nginx/uwsgi_params
/etc/nginx/win-utf
/etc/sysconfig/nginx
/etc/sysconfig/nginx-debug
4.1.2 修改主配置文件
[root@localhost ~]# cd /etc/nginx/conf.d/
[root@localhost conf.d]# vim default.conf
server {
listen 80;
server_name www.shuita.com; #修改为本服务器站点域名
------》wq
4.1.3 安装、配置DNS
- ① 安装、配置DNS解析
[root@localhost conf.d]# yum install bind -y
[root@localhost conf.d]# vim /etc/named.conf
listen-on port 53 { any; }; #修改为any
allow-query { any; }; #修改为any
[root@localhost conf.d]# vim /etc/named.rfc1912.zones
zone "shuita.com" IN { #旧域名
type master;
file "shuita.com.zone";
allow-update { none; };
};
zone "newshuita.com" IN { #新域名
type master;
file "newshuita.com.zone";
allow-update { none; };
};
#添加以上信息,将新、旧解析的域名配置完成
[root@localhost conf.d]# cd /var/named
[root@localhost named]# cp -p named.localhost shuita.com.zone
[root@localhost named]# vim shuita.com.zone
#删除最后一行,添加以下内容
www IN A 192.168.181.140
[root@localhost named]# cp -p shuita.com.zone newshuita.com.zone
[root@localhost named]# ls
data dynamic named.ca named.empty named.localhost named.loopback newshuita.com.zone shuita.com.zone slaves
- ② 启动DNS、Nginx服务
[root@localhost named]# systemctl start named
[root@localhost named]# systemctl start nginx
[root@localhost named]# systemctl stop firewalld.service #关闭防火墙
[root@localhost named]# setenforce 0 #关闭增强性安全功能
- ③ 使用win10虚拟机验证
配置win10的网卡信息
访问服务器站点
4.1.4 修改Nginx主配置文件
[root@localhost conf.d]# vim default.conf
- 重启Nginx服务
[root@localhost conf.d]# systemctl restart nginx
4.1.5 访问旧网址验证
- 清理浏览器缓存、访问旧网址
4.2 场景二:基于客户端IP访问跳转
-
公司业务版本上线,所有IP访问任何内容都显示一个固定维护页面,只有公司IP访问正常
条件一:使用局域网的其他IP地址(非本服务器)访问http://www.shuita.com域名和加参数请求maintenance.html页面内容,状态码是200
条件二:使用http://www.shuita.com/test 带参数访问
4.2.1 修改Nginx主配置文件
- ① 删除上一个跳转访问页面的设置
- ② 修改Nginx主配置文件
[root@localhost conf.d]# vim default.conf
#设置是否合法的IP标记
set $rewrite true;
#合法IP打上标记,remote_addr(客户端IP)地址设置为本机地址
if ($remote_addr = "192.168.181.140"){
#匹配成功,则打上 false标记,允许继续访问
set $rewrite false;
}
#非法IP进行判断打上标记
if ($rewrite = true){
#匹配成功,则跳转至维护页面
rewrite (.+) /maintenance.html;
}
#匹配标记进行跳转站点
location = /maintenance.html {
#指向维护网页的站点目录
root /usr/share/nginx/html;
}
站点目录:
yum安装 Nginx 站点目录为:/usr/share/nginx/html
手工编译安装站点目录:/usr/local/nginx/html
4.2.2 添加维护站点内容
[root@localhost conf.d]# cd /usr/share/nginx/html/
[root@localhost html]# ls
50x.html index.html
[root@localhost html]# vim maintenance.html #添加维护站点内容
<html>
<head>
<meta charset="utf-8">
<title>main</title>
</head>
<body>
<h1>Website maintenance~~~</h1>
<body>
</html>
-------》wq
- 重启Nginx服务
[root@localhost named]# systemctl restart nginx
4.2.3 使用win10访问站点
- 清理浏览器缓存、访问站点
4.2.4 使用本机访问站点
4.3 场景三:基于旧、新域名跳转并加目录
-
假如现在访问的是http://ftp.shuita.com ,现在需要将这个域名下面的发帖都跳转到http://www.shuita.com/ftp (ftp作为目录)
条件:保持域名跳转后的参数不变
4.3.1 修改Nginx配置文件
-
① 将之前配置的内容删除
-
② 修改Nginx主配置文件
-
③ 修改DNS区域数据配置文件
[root@localhost named]# vim shuita.com.zone
#将www修改为ftp,否则客户机则无法解析地址
ftp IN A 192.168.181.140
-------》wq
- ③ 指定DNS
[root@localhost named]# echo "nameserver 192.168.181.140" > /etc/resolv.conf
- ④ 重启DNS、Nginx服务
[root@localhost named]# systemctl restart named
[root@localhost named]# systemctl restart nginx
4.3.2 访问站点验证
- 输入http://ftp.shuita.com/post/a.html进行访问
小结:主配置文件中设置的rewrite (.+) http://www.shuita.com/ftp$1中的**"$1"**包含着/post,我们在访问的时候一定要加上post,否则配置文件中无法匹配到设置的内容
4.4 场景四:基于参数匹配跳转
- 使用浏览器访问http://www.shuita.com/100-(100|200)-100.html,会自动跳转到http://www.shuita.com的页面
4.4.1 修改Nginx主配置文件
- ① 修改主配置文件之前依然删除之前修改的配置
[root@localhost named]# vim shuita.com.zone
www IN A 192.168.181.140 #将最后一行改回www
- 修改主Nginx主配置文件
[root@localhost named]# cd -
/etc/nginx/conf.d
[root@localhost conf.d]# vim default.conf
server {
listen 80;
server_name www.shuita.com; #改回www
#删除原先设置的三行内容后添加以下内容
if ($request_uri ~ ^/100-(100|200)-(\d+).html$){
rewrite (.*) http://www.shuita.com permanent;
}
-------》wq
[root@localhost conf.d]# systemctl restart nginx
4.4.2 访问站点测试
- 依然清除缓存后访问站点
4.5 场景五:基于目录下所有php文件跳转
-
访问http://www.shuita.com/upload/1.php 将跳转到站点首页
现实生活中,假如我将产品页面复制给朋友,朋友访问时也必须进行登录后才可以进行查看
4.5.1 修改Ngnix主配置文件
- 删除之前的配置,再进行修改
[root@localhost conf.d]# vim default.conf
location ~* /upload/.*\.php$ {
rewrite (.+) http://www.shuita.com permanent;
}
--------》wq
[root@localhost conf.d]# systemctl restart nginx
4.5.2 访问站点测试
- 清除缓存后访问php页面
4.6 场景六:基于最普通url请求跳转
- 访问一个具体的页面跳转到首页
4.6.1 修改Nginx配置文件
[root@localhost conf.d]# vim default.conf
#基于场景五的配置,稍作修改即可
location ~* ^/abc/1.html {
rewrite (.+) http://www.shuita.com permanent;
}
-------》wq
[root@localhost conf.d]# systemctl restart nginx
- 重启Nginx服务
[root@localhost conf.d]# vim default.conf
[root@localhost conf.d]# systemctl restart nginx
4.6.2 访问站点测试
总结:
现网环境中,我们需要根据业务、环境要求在三种配置方式中选用合适的方法。配置本篇博客介绍的Nginx的Rwrite功能并不复杂,但是要对正则表达式很熟悉,知道如何去使用规则定位字符串及内容。