目录
一、Nginx Rewrite概述
1.1 Rewrite实际场景
- Nginx跳转需求的实现方式
使用rewrite进行匹配跳转
使用if匹配全局变量后跳转
使用location匹配再跳转 - rewrite放在 server{} , if{} ,location{} 段中
location只对域名后边的除去传递参数外的字符串起作用 - 对域名或参数字符串
使用if全局变量匹配
使用peoxy_pass 反向代理
1.2 Rewrite跳转实现
1.3 Rewrite命令
rewrite <regex>(正则) <replacement>(跳转后的内容) [flag](rewrite 支持的flag标记);
1.3.1 flag标记说明
标记 | 说明 |
---|---|
last | 相当于Apache的[L] 标记,表示完成 |
break | 本条规则匹配完成即终止,不再匹配后面的任何规则 |
redirect | 返回302 临时重定向,浏览器地址会显示跳转后的URL地址,爬虫不会更新url |
permanent | 返回301永久重定向,浏览器地址栏会显示跳转后的URL地址,爬虫更新url |
1.3.2 last 和 break 比较
last | break | |
---|---|---|
使用场景 | 一般写在server和if中 | 一般使用在location中 |
URL匹配 | 不终止重写后的url匹配 | 终止重写后的url匹配 |
1.4 Nginx正则表达式
- 常用的正则表达式元字符
字符 | 说明 |
---|---|
^ | 匹配输入的字符串起始位置 |
$ | 匹配输入字符串的结束位置 |
* | 匹配前面的字符零次或者多次 |
+ | 匹配前面的字符一次或者多次 |
? | 匹配前面的字符零次或者一次 |
. | 匹配除“\n” 之外的任何单个字符,使用诸如“[.\n]”之类的模式,可匹配包括“\n”在内的任意字符 |
\ | 将后面接着的字符标记为一个特殊字符或一个原义字符或一个向后引用 |
\d | 匹配纯数字 |
{n} | 重复n次 |
{n,} | 重复n次 或更多次 |
[c] | 匹配单个字符c |
[a-z ] | 匹配a-z小写字母的任意一个 |
[a-zA-Z] | 匹配a-z小写字母或A-Z大写字母的任意一个 |
二、location分类
- 精准匹配
location = patt {} - 一般匹配
location patt {} - 正则匹配
location ~patt {}
2.1 正则匹配的常用表达式
标记 | 说明 |
---|---|
~ | 执行一个正则匹配,区分大小写 |
~* | 执行一个正则匹配,不区分大小写 |
!~ | 执行一个正则匹配,区分大小写不匹配 |
!~* | 执行一个正则匹配,不区分大小写不匹配 |
^~ | 普通字符匹配;使用前缀匹配。如果匹配成功,则不再匹配其他location |
= | 普通字符精确匹配,也就是完全匹配 |
@ | 定义一个命名的location ,使用在内部定向时 |
2.2 location优先级
- 相同类型的表达式,字符串长的会优先匹配
- 按优先级排列
= 类型
^~ 类型表达式
正则表达式(和*)类型
常规字符串匹配类型,按前缀匹配
通用匹配(/),如果没有其他匹配,任何请求都会匹配到
2.3 比较 rewrite 和location
- 相同点
都能实现跳转 - 不同点
rewrite是在同一域名内更改获取资源的路径
location是对一类路径做控制访问或反向代理 ,还可以 proxy_pass 到其他机器 - rewrite 会写在location里,执行顺序
执行server块里面的rewrite指令
执行location匹配
执行选定的location中的rewrite指令
2.4 location优先级的示例
location = /{
## 精确匹配,主机名后面不能带任何字符串
[configuration A]
}
location /{
## 所有的地址都以 /开头,这条规则将匹配到所有请求,但正则和最长字符串会优先匹配
[configuration B]
}
location /documents/ {
##匹配任何以 /documents/ 开头的地址,当后面的正则表达式没有匹配到时,才起作用
[configuration C]
}
location ~ /documents/abc{
##匹配任何以 /documents/abc 开头的地址,当后面的正则表达式没有匹配到时,才会起作用
[configuration D]
}
三、基于不同场景的应用
3.1 应用场景——基于旧、新域名跳转并加目录
3.1.1 安装nginx
[root@promote ~]# rpm -Uvh http://nginx.org/packages/centos/7/noarch/RPMS/nginx-release-centos-7-0.el7.ngx.noarch.rpm ## 获取rpm安装源
[root@promote ~]# yum -y install nginx ## 安装nginx
3.1.2 安装配置DNS解析服务
[root@promote ~]# yum -y install bind
[root@promote ~]# vim /etc/named.conf
listen-on port 53 {
any; };
allow-query {
any; };
[root@promote ~]# vim /etc/named.rfc1912.zones
zone "accp.com" IN {
type master;
file "accp.com.zone";
allow-update {
none; };
};
zone "test.com" IN {
type master;
file "test.com.zone";
allow-update {
none; };
};
[root@promote ~]# cd /var/named/
[root@promote named]# cp -p named.localhost accp.com.zone
[root@promote named]# cp -p named.localhost test.com.zone
[root@promote named]# vim accp.com.zone
$TTL 1D
@ IN SOA @ rname.invalid. (
0 ; serial
1D ; refresh
1H ; retry
1W ; expire
3H ) ; minimum
NS @
A 127.0.0.1
www IN A 192.168.233.140
~
~
[root@promote named]# vim test.com.zone
$TTL 1D
@ IN SOA @ rname.invalid. (
0 ; serial
1D ; refresh
1H ; retry
1W ; expire
3H ) ; minimum
NS @
A 127.0.0.1
www IN A 192.168.233.140
~
~
3.1.3 Nginx 的配置
[root@promote ~]# vim /etc/nginx/conf.d/default.conf
server_name www.accp.com;
access_log /var/log/nginx/host.access.log main;
location / {
if ($host = 'www.accp.com'){
rewrite ^/(.*) http://www.test.com/$1 permanent;
}
root /usr/share/nginx/html;
index index.html index.htm;
}
3.1.4 启动服务 测试
[root@promote ~]# iptables -F
[root@promote ~]# setenforce 0
[root@promote ~]# systemctl start nginx
[root@promote ~]# systemctl start named
- 访问 www.appc.com/index.php ##虽然站点没有那个目录,但是依然会跳转
[root@promote ~]# echo "nameserver 192.168.233.140" > /etc/resolv.conf ## 指定DNS解析服务器地址
3.2 基于端口IP访问跳转
3.2.1 Nginx 配置及站点设置
[root@promote ~]# vim /etc/nginx/conf.d/default.conf
set $rewrite true;
if ($remote_addr = "192.168.233.99"){
set $rewrite false;
}
if ($rewrite = true) {
rewrite (.+) /main.html;
}
location = /main.html {
root /usr/share/nginx/html;
}
[root@promote ~]# cd /usr/share/nginx/html/
<h1>weihuzhong.....</h1>
[root@promote html]# systemctl restart nginx
3.2.2 测试
- 当IP地址为 192.168.233.99 访问网站
- 当IP地址不是99 去访问网站
3.3 基于旧域名跳转新域名后面加目录
3.3.1 Nginx 配置文件的修改
[root@promote ~]# vim /etc/nginx/conf.d/default.conf
location /post {
rewrite (.+) http://www.accp.com/bbs$1 permanent;
}
3.3.2 named区域数据配置文件修改
[root@promote ~]# vim /var/named/accp.com.zone
$TTL 1D
@ IN SOA @ rname.invalid. (
0 ; serial
1D ; refresh
1H ; retry
1W ; expire
3H ) ; minimum
NS @
A 127.0.0.1
bbs IN A 192.168.233.140
3.3.3 测试
- 访问 bbs.accp.com/post/abc.html
- 网页跳转 http://www.accp.com/bbs/post/abc.html
3.4 基于参数匹配的跳转
3.4.1 修改Nginx配置文件
[root@promote ~]# vim /etc/nginx/conf.d/default.conf
server_name www.accp.com;
access_log /var/log/nginx/host.access.log main;
if ($request_uri ~ ^/100-(100|200)-(\d+).html$){
rewrite (.*) http://www.accp.com permanent;
}
[root@promote ~]# systemctl restart nginx
3.4.2 测试
- 访问 www.accp.com/100-100-100.html
- 访问后页面跳转
3.5 基于目录下所有php结尾的文件跳转
3.5.1 Nginx配置文件修改
[root@promote ~]# vim /etc/nginx/conf.d/default.conf
server_name www.accp.com;
access_log /var/log/nginx/host.access.log main;
location ~* /upload/.*\.php$ {
rewrite (.+) http://www.accp.com permanent;
}
[root@promote ~]# systemctl restart nginx
3.5.2测试
-
访问页面www.accp.com/upload/1.php
-
跳转到http://www.accp.com/
3.6 基于最普通一条 url 请求的跳转,访问一个具体的页面跳转到首页下
3.6.1 Nginx配置文件修改
[root@promote ~]# vim /etc/nginx/conf.d/default.conf
server_name www.accp.com;
access_log /var/log/nginx/host.access.log main;
location ~* ^/1/test.html {
rewrite (.+) http://www.accp.com permanent;
}
[root@promote ~]# systemctl restart nginx
3.6.2 测试
- 访问 www.accp.com/1/test.html
- 跳转www.accp.com 页面