前言:
网页更换域名后需要保持旧的域名能跳转到新的域名上、某网页发生改变需要跳转到新的页面、网站防盗链等等需求。如果在后端使用的 Apache 服务器,虽然也能做跳转,规则库也很强大,但是用 Nginx跳转效率会更高(正则精确匹配)
nginx跳转需求的实现方式
- 使用rewrite进行匹配跳转
- 使用if匹配全局变量后跳转
- 使用location匹配再跳转
rewrite跳转
从功能看 rewrite和 location 似乎有点像,都能实现跳转,主要区别在于rewrite是在同一域,location是对一类路径做控制访问或反向代理,还可以proxy_pass到其他机器。
rewrite跳转场景
- 调整用户浏览的URL,看起来更规范,合乎开发及产品人员的需求。
- 为了让搜索引擎搜寻网站内容及用户体验更好,企业会将动态URL地址伪装成静态地址提供服务。
- 网址换新域名后,让旧的访问跳转到新的域名上。例如,访问京东的360buy.com会跳转到jd.com
- 服务端某些业务调整,比如根据特殊变量、目录、客户端的信息进行URL调整等。
rewrite跳转实现
- Nginx:通过ngx_http_rewrite_module 模块支持URL重写、支持if条件判断,但不支持else跳转:从一个location跳转到另一个location(循环最多可以执行10次,超过后nginx将返回500错误)
- PCRE支持: perl兼 容正则表达式的语法规则匹配
- 重写模块set指令:创建新的变量并设其值
rewrite放在server{},if{},location{}段中
- location只对域名后边的除去传递参数外的字符串起作用
对域名或参数字符串匹配
- 使用if全局变量匹配
- 使用proxy_pass反向代理
常用nginx正则表达式
^:匹配输入字符串的起始位置
$:匹配输入字符串的结束位置
*:匹配前面的字符零次或多次
+:匹配前面的字符一次或多次
?:匹配前面的字符零次或一次
. :匹配除\n之外的任何单个字符
\:转义符
\d:匹配纯数字
{n}:重复n次
{n,}:重复n次或更多次
[c]:匹配单个字符c
[a-z]:匹配a-z小写字母的任意一个
[a-zA-Z0-9]:匹配a-z小写字母或A-Z大写字母或数字的任意一个
() : 表达式的开始和结束位置
| : 或运算符
rewrite语法
rewrite < regex > < replacement > < flag >;
- regex:表示正则匹配规则。
- replacement:表示跳转后的内容。
- flag: 表示rewrite 支持的flag标记。
flag标记说明
-
last:本条规则匹配完成后,继续向下匹配新的location URL规则,一般用在server和 if中。
-
break:本条规则匹配完成即终止,不再匹配后面的任何规则,一般使用在location中。
-
redirect:返回302临时重定向,浏览器地址会显示跳转后的URL地址。
-
permanent:返回301永久重定向,浏览器地址栏会显示跳转后的URL地址。
注: last和break最 大的不同在于
- break是终止当前locat ion的rewrite检测,而且不再进行location匹配
- last是终止当前location的rewrite检测,但会继续重试location匹配并处理区块中的rewrite规则
location
location分类
- 精准匹配
location = / {} - 一般匹配
location patt {} - 正则匹配
location ~ patt {}
location常用的匹配规则
- =:进行普通字符精确匹配,也就是完全匹配
- ^~:表示普通字符匹配。使用前缀匹配。如果匹配成功,则不再匹配其他location
- ~:区分大小写的匹配
- ~*:不区分大小写的匹配
- !~:区分大小写的匹配取非
- !~*:不区分大小写的匹配取非
- @:定义一个location, 使用在内部定向的时候
location优先级
相同类型的表达式,学符串长的优先匹配
首先精确匹配 =
其次前缀匹配 ^~
其次是按文件中顺序的正则匹配 ~ 或~*
然后匹配不带任何修饰的前缀匹配,示例: /images/ abc/1. html
最后是 / 通用匹配
location优先级规则
- 匹配某个具体文件:
(location = 完整路径)>
(location ^~ 完整路径) >
(location ~* 完整路径) = (location ~ 完整路径) >
(location 完整路径) >
(location /)
- 用目录做匹配访问某个文件:
(location = 目录)>
(location ^~ 目录)>
(location ~* 目录)=(location ~ 目录)>
(location /)
rewrite和location区别
相同点:都能实现跳转
不同点:
- rewrite是在同一域名内更改获取资源的路径
- location是对一类路径控制访问或反向代理,还可以proxy_pass到其他机器
rewrite会卸载location里,执行顺序为:
- 执行server块里面的rewrite指令
- 执行location匹配
- 执行选定的location中的rewrite指令
location优先级实例
location = / { #精准匹配/,主机名后面不能带任何字符串
[configuration A]
}
location / { #所有的地址都以/开头,这条规则将匹配到所有请求,但正则和最长字符串会优先匹配
[configuration B]
}
location /documents/ { #匹配任何以/documents/开头的地址,当后面的正则i奥达斯没有匹配到时,才起作用
[configuration C]
}
location ~ /documents/abc { #匹配任何以/documents/abc开头额地址,当后妈的正则表达式没有匹配到时,才会起作用
[configuraton D]
}
location ^~ /images/ { #以/images/开头的地址,匹配复核后,停止往下匹配
[configuration E]
}
location ~*/.(gif|jpg|jpeg)$ { #匹配所有以gif.jpg或jpeg结尾的请求,/images/下的图片会被[configuration E]处理,因为^~优先级更高
[configuration F]
}
location /images/abc { #最长字符匹配到/images/abc,优先级最低
[configuration G]
}
location ~ /images/abc { #以/images/abc开头的,优先级次之
[configuration H]
}
location /images/abc/1.html { #如果和正则~ /images/abc/1.html相比,正则优先级更高
[configuration I]
}
跳转实验
基于域名的跳转
现在公司旧域名www.xxzw.com有业务需求变更,需要使用新域名www.benet.com代替,但是旧域名不能废除,需要跳转到新域名上,而且后面的参数保持不变。
1.添加映射
[root@www ~]# vim /etc/hosts
192.168.233.103 www.xxzw.com
2.修改配置文件
[root@www ~]# vim /usr/local/nginx/conf/nginx.conf
3.编辑html
[root@www ~]# vim /usr/local/nginx/html/index.html
<h1>www.xxzw.com</h1>
基于客户端IP地址访问跳转
要求:公司业务新版本上线,要求所有IP访问任何内容都显示一个固定维护页面,只有公司IP192.168.233.101访问正常
1.修改配置文件
[root@www ~]# vim /usr/local/nginx/conf/nginx.conf
2.创建html文件
[root@www ~]# mkdir -p /var/www/html
[root@www ~]# echo "<h1>this is weihu web</h1>" > /var/www/html/weihu.html
本机访问网页
其他主机访问网页
基于旧域名跳转到新域名后面加目录
要求:访问http://www.xxzw.com/post/1.html都跳转到www.benet.com/bbs/post/1.html下
1.创建目录
[root@www html]# echo "this is 1.html" >> /usr/local/nginx/html/bbs/post/1.html
[root@www html]# echo "192.168.233.103 www.benet.com" >> /etc/hosts
2.修改配置文件
[root@www html]# vim /usr/local/nginx/conf/nginx.conf
域名后参数不变
基于参数匹配的跳转
要求:访问www.xxzw.com/100-(100|200)-100.html跳转到www.xxzw.com的页面
修改配置文件
[root@www html]# vim /usr/local/nginx/conf/nginx.conf
基于目录下所有php结尾的文件跳转(用于账户注册)
设置配置文件
[root@www html]# vim /usr/local/nginx/conf/nginx.conf
基于最普通的一条url请求的跳转
设置配置文件
[root@www html]# vim /usr/local/nginx/conf/nginx.conf