Nginx服务的跳转Rewrite正则表达式
Posted 可乐卷儿
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Nginx服务的跳转Rewrite正则表达式相关的知识,希望对你有一定的参考价值。
前言
现在nginx已经成为很多公司作为前端反向代理(proxy_ pass) 服务器的首选,在实际工作中往往会遇到很多跳转( 重写URL)的需求。
比如:更换域名后需要保持旧的域名能跳转到新的域名上、某网页发生改变需要跳转到新的页面、网站防盗链等等需求。如果在后端使用的Apache 服务器,虽然也能做跳转,规则库也很强大,但是用Nginx 跳转效率会更高
一、Rewrite实际场景
1、配置跳转的原因
- 为了让URL看起来更规范、合理
- 企业会将动态URL地址伪装成静态地址提供服务
- 网址换新域名后,期望用户可以通过旧的访问跳转到新的域名上
- 服务端某些业务调整
2、Nginx跳转需求的实现方式
- 使用rewrite进行匹配跳转(主要匹配的是具体的路径)
- 使用if匹配全局变量后跳转,结合布尔值时间true和fales的跳转
- 使用location匹配再跳转(可以匹配后执行proxy_pass,将请求跳转到其他服务上)
3、rewrite如何实现跳转
- nginx服务基于http协议rewrite重写mudule模块
- nginx:主从URL重写,其中有一个布尔值:返回值的结果只有true或者false;同时特性:只支持if单分支语句
- 跳转:循环最多可以执行10次,超过后nginx将返回500错误
- PCRE支持:perl兼容正则表达式的语法规则匹配
- 重写模块set指令:自己设置即可以使用布尔值
如下:标志位参数:$1:具体的路径,即标志位
www.baidu.com/bbs/install/index.php ##URL
www.baidu.com ##URI $0
/bbs/install/index.php ## $1
3、rewrite功能
- rewrite功能就是,使用nginx提供的全局变量或自己设置的变量,结合正则表达式和标记位实现URL重写以及重定向。
- 比如:更换域名后需要保持旧的域名能跳转到新的域名上、某网页发生改变需要跳转到新的页面、网站防盗链等等需求
4、rewrite生效位置
- rewrite只能放在server{},location{},if{}中,并且默认只能对域名后边的除去传递的参数外的字符串起作用,
- 例如http:/ /www . dabao. com/a/we/ index。php?id=1&u=str 只对/a/we/ index . php重写
- 例如http:/ /www . dabao. com/a/we/ index。php?id=1&u=str 只对/a/we/ index . php重写
5、rewrite 执行顺序
- 执行server 模块里面的rewrite 指令。
- 执行选定的location 中的rewrite 指令。
- 执行选定的location中 if中的rewrite指令
示例:
http {
server {
rewrite #优先级1
location ~*.(jpgIgif|swf)$ {
rewrite #优先级2
valid_ referers none blocked *.dog.com dog.com;
if ( $invalid referer ) {
rewrite ^/ http: L /www. dog. com/error.png; #优先级3
}
}
}
}
6、对域名或参数字符串
- 使用if全局变量匹配
- 使用proxy_ _pass反向代理
- 把服务端的请求交给后面的服务处理
首先ip地址定位,如何定位,
- 把服务端的请求交给后面的服务处理
upstream apache_server { ##定义的是动态处理服务的地址池
apache-1_ip:端口
apache-2_ip:端口
}
通过location内的正常匹配去调用apache_server
location {
proxy_pass apache_server
}
apache_server:是一个函数,是可以自定义**_server,需要upstream和location名字一致
二、Nginx正则表达式
1、字符说明
^ 匹配输入字符串的起始位置
$ 匹配输入字符串的结束位置
* 匹配前面的字符0次或多次
+ 匹配前面的字符1次或多次
? 匹配前面的字符0次或1次
. 匹配除“\\n”之外的任何单个字符;字母,数字,符号都包含
\\ 将后面接着的字符标记为一个特殊字符或一个原义字符或一个向后引用;使用诸如"[.\\n]" 之类的模式,可匹配包括"\\n" 在内的任意字符
\\w 匹配字母或数字或下划线或汉字
\\s 匹配任意的空白符
\\b 匹配单词的开始和结束
\\d 匹配纯数字
{n} 重复n次
{n,} 重复n次或更多次
[] 定义匹配的字符范围
[c] 匹配单个字符c
[a-z] 匹配a-z小写字母的任意一个
[a-zA-Z] 匹配a-z小写字母或A-Z大写字母的任意一个
() 表达式的开始和结束
| 或的运算符
2、rewrite 命令
- 基本格式:
- rewrite [flag];
- regex:表示正则匹配规则
- replacement:表示跳转后的内容
- flag:表示rewrite支持的flag标记
- 其中flag标记说明包含以下
- last:相当于Apache的以标记,表示完成rewrite
- break 本条规则匹配完成即终止,不再匹配后面的任何规则
- redirect 返回302 临时重定向,浏览器地址会显示跳转后的URL地址,爬虫不会更新url
- permanent 返回301永久重定向,浏览器地址栏会显示跳转后的URL地址
- rewrite [flag];
last和break比较
last | break | |
---|---|---|
使用场景 | 一般写在server和if中 | 一般使用在location中 |
URL匹配 | 不终止重写后的urI匹配 | 终止重写后的url匹配 |
三、location分类
分类主要是为了匹配的优先级顺序
1、location分类
- 精准匹配:location = / {…} 示例:location = patt {} PS: 精确匹配字符串
- 一般匹配:location / {…} 示例:location patt {} PS:只要包含patt的字符串即可
- 正则匹配: location ~ / {…} 示例:location~patt{}PS:按照正则表达式的方式匹配
- ~:表达的意思首先是可以支持正则表达式,其次是区分大小写
2、location 优先级
- =:精确匹配
- ^~:前缀匹配
- 和*:按文件中的顺序的正则匹配;这里区分匹配是文件还是目录
- 文件:*优先级高于
- 目录:优先级高于*
- 普通匹配:以xxx路径为前缀的匹配
- /:通用匹配
3、Rewrite和Location的小结
- 相同点:都能实现跳转
- 不同点:
- rewrite是在同一域名内更改获取资源的路径
- location是对一类路径做控制访问或反向代理,还可以 proxy_ pass到其他机器
- rewrite会写在location里,执行顺序
- 执行server块里面的rewrite指令
- 执行location匹配
- 执行选定的location中的rewrite指令
4、实际网站使用中,至少有三个匹配规则
-------------->第一个必选规则:直接匹配网站根,通过域名访问网站首页比较频繁(www.baidu.com/),使用这个会加速处理,比如说官网。
可以是一个静态首页,也可以直接转发给后端应用服务器.
location = / {
root html ;
index index.html index.htm;
}
--------------->第二个必选规则是处理静态文件请求,这是nginx作为http服务器的强项
有两种配置模式,目录匹配或后缀匹配,任选其--或搭配使用
location ^~ /static/ {
root /webroot/static/ ;
}
location ~* \\. (html|gif|jpg|jpeglpnglcssljslico)$ {
root /webroot/res/ ;
}
---------------->第三个规则就是通用规则,比如用来转发带.php、.jsp后缀的动态请求到后端应用服务器,非静态文件请求就默认是动态请求,即跳转或反向代理
upstream tomcat_ server {
192.168.226.128:80
192.168.226.132:80
location / {
proxy_ pass http: //tomcat_server;
}
四、跳转的优化
1、基于域名的跳转
业务需求:现在公司旧域名www.kgc.com有业务需求变更,需要使用新域名www.benet.com代替,但是旧域名不能废除,需要跳转到的域名,而且后面的参数保持不变
- 代码编写
vim /etc/hosts #添加映射
192.168.35.40 www.zyt.com www.zw.com
mkdir -p /var/log/nginx/
vim /usr/local/nginx/conf/nginx.conf ##修改配置文件
server {
listen 80;
server_name www.zyt.com; ##域名修改
#charset koi8-r;
access_log /var/log/nginx/www.zyt.com-access.log; ##开启并对日志保存路径进行修改
location / { ##在原有location位置插入
if ($host = 'www.zyt.com'){ ##$host为rewrite全局变量,代表请求主机头字段或主机名
rewrite ^/(.*)$ http://www.zw.com/$1 permanent; ##$1为匹配的位置变量,即域名后面的字符串,同时永久跳转;(.*)
}
root html;
index index.html index.htm;
}
systemctl stop nginx
systemctl start nginx
需注意使用windows测试需要先映射
本机需要添加映射:c盘–windows–System32–drivers–etc–hosts–ctrl+s(保存)
- 测试
访问http://www.zyt.com自动跳转到www.zw.com
同时可以访问http://www.zyt.com/1.html在显示错误页面的同时可以看到域名也会变化为www.zw.com/1.html
2、基于客户端IP访问跳转
业务需求:今天公司业务新版本上线,要求所有IP访问任何内容都显示一个固定维护页面,只有公司IP 192. 168.35.40访问正常
- 代码编写
mkdir -p /var/log/nginx/
mkdir -p /var/www/html
echo '<h1>页面维护中...</h1>' > /var/www/html/weihu.html
vim /usr/local/nginx/conf/nginx.conf
server {
listen 80;
server_name www.zyt.com
#charset koi8-r;
access_log /var/log/nginx/www.zyt.com-access.log ; ##开启并对日志保存路径进行修改
----------------------------->设置是否是合法的IP标记<--------------------------------
set $rewrite true; #设置变量$rewrite,变量值为布尔值为true
----------------------------->设置是否是合法的IP标记<--------------------------------
if ($remote_addr = '192.168.35.40') { #当变量值为true时,进行重写
set $rewrite false;
}
----------------->除了合法IP,其它都是非法IP,进行重写跳转到维护页面<----------------------------
if ($rewrite = true) { ##$remote_ addr:全局变量;当客户端IP为192.168.35.40时,将变量值设为flase,不进行重写
rewrite (.+) /weihu.html; ##重写在访问IP后边插入/weihu. html,例如 192.168.35.40/weihu.html
}
location = /weihu.html { ##增加location
root /var/www/html ##页面返回/var/www/html /weihu. html的内容
}
location / {
root html;
index index.html index.htm;
}
systemctl stop nginx
systemctl start nginx
- 测试
3、基于旧域名跳转到新域名后面加目录
业务需求:当访问的是http://bbs.zyt.com/post/1.html会自动跳转到http: //www.zw.com/bbs/post/1.html
- 代码编写
----------------->首先创建一个bbs目录下post的网页文件,并编辑网页文件,做一个映射<----------------
mkdir -p /usr/local/nginx/html/bbs/post ##创建指定目录
echo "<h1>this is 1.html </h1>" >> /usr/local/nginx/html/bbs/post/1.html
echo "192.168.35.40 bbs.zyt.com" >> /etc/hosts
vim /usr/local/nginx/conf/nginx.conf
server {
listen 80;
server_name bbs.zyt.com; ##更改域名
#charset koi8-r;
access_log /var/log/nginx/www.zyt.com-access.log ; ##开启并对日志保存路径进行修改
location /post { ##添加location;以post开头匹配
rewrite (.+) http://www.zw.com/bbs$1 permanent; ##$1为位置变量,代表/post
}
location / {
root html;
index index.html index.htm;
}
systemctl stop nginx
systemctl start nginx
本机添加映射
- 测试
浏览器访问:http://bbs.zyt.com/post/1.html跳转的是http://bbs.zw.com/post/1.html
4、基于参数匹配(多余)的跳转
业务需求:现在访问http://www.zyt.com/100-(100|200)-100.html会跳转到http://www.zw.com的页面
- 代码编写
vim /usr/local/nginx/conf/nginx.conf
server {
listen 80;
server_name www.zyt.com; ##更改域名
#charset koi8-r;
access_log /var/log/nginx/www.zyt.com-access.log ; ##开启并对日志保存路径进行修改
if ($request_uri ~ ^/100-(100|200)-(\\d+)\\.html$){ ##$repuest_uri内置变量,表示URI
rewrite (.*) http://www.zyt.com permanent;
}
location / {
root html;
index index.html index.htm;
}
systemctl stop nginx
systemctl start nginx
使用浏览器访问http://www.zyt.com/100-100-100.html会跳转到http://www.zw.com的页面
5、基于目录下所有php结尾的文件跳转
业务需求:要求访问http://www.zyt.com/upload/123.php跳转到首页(常用场景:网站新用户提示需要注册)
- 代码编写
vim /usr/local/nginx/conf/nginx.conf
server {
listen 80;
server_name www.zyt.com;
#charset koi8-r;
access_log /var/log/nginx/www.zyt.com-access.log ;
location ~* /upload/.*\\.php$ { ##~*:正则匹配,不区分大小写;匹配/upload目录下所有以.php结尾的文件
rewrite (.*) http://www.zyt.com permanent;
}
location / {
root html;
index index.html index.htm;
}
systemctl stop nginx
systemctl start nginx
- 测试
6、基于最普通一条url请求的跳转
业务需求:要求访问一条url 请求的跳转
- 代码编写
vim /usr/local/nginx/conf/nginx.conf
server {
listen 80;
server_name www.zyt.com;
#charset koi8-r;
access_log /var/log/nginx/www.zyt.com-access.log ;
location ~* /abc/123.html { ##添加location
rewrite (.+) http://www.zyt.com permanent;
}
location / {
root html;
index index.html index.htm;
}
systemctl stop nginx
systemctl start nginx
- 测试
浏览器访问http://www.zyt.com/abc/123.html,跳转到首页
五、总结
本章介绍了Nginx服务的跳转,以及正则表达式的使用方法,nginx跳转的优化结合实例进行说明
以上是关于Nginx服务的跳转Rewrite正则表达式的主要内容,如果未能解决你的问题,请参考以下文章
Nginx rewrite 重写功能和Nginx的正则表达式