Nginx 重写功能(Rewrite)
目录
一、Nginx Rewrite概述
二、Nginx Rewrite基本操作
三、案例
1、基于域名的跳转
2、基于客户端 IP 访问跳转
3、基于旧域名跳转到新域名后面加目录
4、基于参数匹配(多余的)的跳转
5、基于目录下所有 php 结尾的文件跳转
6、基于最普通一条 url 请求的跳转
一、Nginx Rewrite概述
location是为了匹配访问的路径(URL)
URL:就是一个具体路径/位置
URI:指的是一个拥有相同类型/特性的对象集合
Rewrite跳转场景
URL看起来更规范、合理
企业会将动态URL地址伪装成静态地址提供服务
网址换新域名后,让旧的访问跳转到新的域名上
服务端某些业务调整
Rewrite跳转实现
1.Nginx是通过ngx_http_rewrite_module模块支持url重写、支持if条件判断,但不支持else。
(Nginx哪些模块:核心/全局模块、HTTP模块、server模块、location if rewrite)
2.另外该模块需要PCRE支持,应在编译Nginx时指定PCRE支持,默认已经安装。
3.根据相关变量重定向和选择不同的配置,从一个location跳转到另一个location,不过这样的循环最多可以执行10次,超过后Nginx将返回500错误。
4.同时,重写模块包含set指令,来创建新的变量并设其值,这在有些情景下非常有用的,如记录条件标识、传递参数到其他location、记录做了什么等等。
Rewrite实际场景
Nginx跳转需求的实现方式
使用rewrite进行匹配跳转
使用if匹配全局变量后跳转
使用location匹配再跳转(匹配的访问 路径URL location可以匹配本地的重写以及跨服务器的跳转)
rewrite放在server{}, if{},location{}段中
(多个server模块 sever模块里包含location location包含if if里面包含rewrite)
location只对域名后边的除去传递参数外的字符串起作用
对域名或参数字符串
使用if全局变量匹配
使用proxy_pass反向代理
Nginx正则表达式(什么是正则表达式:正则是作为精确匹配、过滤、筛选的一种执行规范)
作用:1、精确匹配,减少遍历的消耗
2、节省服务响应的资源消耗
3、提高用户体验感
4、提高服务器并发时、处理效率/性能
Nginx使用正则的作用:
Nginx作为运维角度前段接受、想用客户请求的直接对服务器所以需要考虑到Nginx的执行效率(精确匹配-类比)、性能(资源消耗)、抗压能力(高并发时处理能力)、用户体验感(用户访问群体)
^ :匹配输入字符串的起始位置
$ :匹配输入字符串的结束位置
* :匹配前面的字符零次或多次。如“ol*”能匹配“o”及“ol”、“oll”
+ :匹配前面的字符一次或多次。如“ol+”能匹配“ol”及“oll”、“olll”,但不能匹配“o”
? :匹配前面的字符零次或一次,例如“do(es)?”能匹配“do”或者“does”,”?”等效于”{0,1}”
. :匹配除“\n”之外的任何单个字符,若要匹配包括“\n”在内的任意字符,请使用诸如“[.\n]”之类的模式
\ :将后面接着的字符标记为一个特殊字符或一个原义字符或一个向后引用。如“\n”匹配一个换行符,而“\$”则匹配“$”
\d :匹配纯数字
\w :匹配字母或数字或下划线或汉字
\s :匹配任意的空白符
\b :匹配单词的开始或结束
{n} :重复 n 次
{n,} :重复 n 次或更多次
{n,m} :重复 n 到 m 次
[] :定义匹配的字符范围
[c] :匹配单个字符 c
[a-z] :匹配 a-z 小写字母的任意一个
[a-zA-Z0-9] :匹配所有大小写字母或数字
() :表达式的开始和结束位置 例如:(jpg|gif|swf|)
| :或运算符
Rewrite命令语法
last和break比较
last break
使用场景 一般写在server和if中 一般使用在location中
URL匹配 不终止重写后的url匹配 终止重写后的url匹配
location的分类
精准匹配:location = / {…} 示例: location = patt {} PS: 精确匹配字符串
一般匹配:location / {…} 示例: location patt {} PS: 只要包含patt的字符串即可
正则匹配:location ~ / {…} 示例: location ~ patt {} PS: 按照正则表达式的方式匹配
location 常用的匹配规则
=:进行普通字符精确匹配,也就是完全匹配
^~:表示普通字符匹配。使用前缀匹配。如果匹配成功,则不再匹配其他 location
~:区分大小写的匹配
~*:不区分大小写的匹配
!~:区分大小写的匹配取非
!~*:不区分大小写的匹配取非
@:定义一个location,使用在内部定向的时候
location 优先级
相同类型的表达式,字符串长的优先匹配
原则:越精确、越优先
首先精确匹配 =
其次前缀匹配 ^~(匹配普通字符、且为前缀匹配)
其次是按文件中顺序的正则匹配 ~或~*(宏观而言——》是否区分大小写)
然后匹配不带任何修饰的前缀匹配,示例:/images/abc/(location /patt)
最后是交给 / 通用匹配
location 示例说明
location 优先级总结
匹配某个具体文件
(location = 完整路径) > (location ^~ 完整路径) > (location ~* 完整路径) > (location ~ 完整路径) > (location 完整路径) > (location /)
location ~* 完整路径 > location ~ 完整路径 /path
用目录做匹配访问某个目录
(location = 目录) > (location ^~ 目录/) > (location ~ 目录) > (location ~* 目录) > (location 目录) > (location /)
实际网站使用中,三个匹配规则定义
#第一个必选规则
直接匹配网站根,通过域名访问网站首页比较频繁(www.baidu.com/),使用这个会加速处理,比如说官网。
可以是一“个静态首页,也可以直接转发给后端“应用服务器” ——》PHP 、Apache
location = / {
root html;
index index.html index. htm;
}
#第二个必选规则是处理静态文件请求,这是nginx作为http服务器的强项(1、静态请求处理的能力+ 高并发处理能力+资源消耗较低)
有两种配置模式,目录匹配或后缀匹配,任选其一或搭配使用
location ^~ /static/ {
root /webroot/static/ ;
}
location ~* \. (html Igif ljpg ljpeglpnglcssljslico)$ {
root /webroot/res/ ;
}
#⭐⭐⭐⭐第三个规则就是通用规则,比如用来转发带.php、.jsp后缀的动态请求到后端应用服务器
非静态文件请求就默认是动态请求(跳转/反向代理)
upstream tomcat_server {
server 192.168.226.128:8080 weight 1;
server 192.168.226.132:8080 weight 1;
}
location ^/ \.(php|jsp)$ {
proxy_pass http://tomcat_server;
}
比较rewrite和location
相同点:
都能实现跳转
不同点:
rewrite是在同一域名内更改获取资源的路径
location是对一类路径做控制访问或反向代理,还可以proxy_pass到其他机器
rewrite改写访问的URL路径(被访问的HTML/HTM/CSS文件)
location对一类地址进行权限控制(认证控制)+跳转(跨服务器进行URL跳转)
rewrite会写location里,执行顺序
执行server块里面的rewrite指令
执行location匹配
执行选定的location中的rewrite指令
理论总结
rewrite:基本概念、应用场景、使用特点
rewrite执行方式三种
rewrite regex replacement flag
location 优先级
location 和rewrite区别
三、案例
1、基于域名的跳转
#添加映射
vim /etc/hosts
192.168.226.132 www.benet.com www.kgc.com
#创建日志目录
mkdir -p /var/log/nginx/
#修改配置文件
vim /usr/local/nginx/conf/nginx.conf
#在usr/local/nginx/html
创建个test.html
此时访问 www.kgc.com 时会自动跳转到 www.benet.com 上进行访问。
访问www.kgc.com/test.html 时会自动跳转到 www.benet.com/test.html 上进行访问。
2、基于客户端 IP 访问跳转
今天公司业务新版本上线,要求所有(外部来访) IP 访问任何内容都显示一个固定维护页面,只有公司 IP 192.168.147.3访问正常。
① 删除上一个实验的配置
mkdir -p /var/www/html
echo '<h1>this is weihu web!</h1>' > /var/www/html/weihu.html
systemctl restart nginx.service
其他主机访问页面
192.168.147.4访问页面
整理下:1、set $rewrite true; ->目的:给所有client端打上true标签
2、if($remote_addr='192.168.147.4')
3、if($rewrite=true)对于具有true标签的来源,进行全部匹配,并且重写路径为weihu.html
4、location=/weihu.html 匹配访问路径为/weihu.html的请求,指向页面的文件位置(路径)
3、基于旧域名跳转到新域名后面加目录
当访问的是 http://bbs.kgc.com/post/1.html 会自动跳转到 http://www.benet.com/bbs/post/1.html
#创建指定目录
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.147.4 bbs.kgc.com" >> /etc/hosts
systemctl restart nginx.service
此时用浏览器访问 http://bbs.kgc.com/post/1.html 会自动跳转到 http://www.benet.com/bbs/post/1.html
4、基于参数匹配(多余的)的跳转
现在访问 http://www.kgc.com/100-(100|200)-100.html 会跳转到 http://www.kgc.com的页面
使用浏览器访问 http://www.kgc.com/100-100-100.html 或 http://www.kgc.com/100-200-100.html会自动跳转到 http://www.kgc.com页面
5、基于目录下所有 php 结尾的文件跳转
要求访问 http://www.kgc.com/upload/123.php 跳转到首页www.kgc.com (场景:注册/登陆)
浏览器访问 http://www.kgc.com/upload/123.php 跳转到 http://www.kgc.com 首页
6、基于最普通一条 url 请求的跳转