1.Rewrite
1.1Rewrite跳转场景
- URL看起来更规范、合理
- 企业会将动态URL地址伪装成静态地址提供服务
- 网页更换新域名后,让旧的访问跳转到新的域名上
- 服务端某些业务跳转
1.2Rewrite跳转实现
Nginx利用ngx_http_rewrite_module模块解析和处理rewrite请求。Rewrite用于实现URL重写,其实有点类似于重定向功能,可以将用户的请求重写至别的目录,在一定程度上提高了网站安全性。Rewrite支持if条件判断,但不支持else判断。而且Rewrite需要PCRE支持,一次重定向最多可以跳转10次,超过10次将返回500错误。Rewrite模块包含set命令,可以创建变量用来记录条件标识或者传递变量到其他的Location中。Rewrite实际上就是使用Nginx已有的全局变量或者通过set命令设置的变量结合正则表达式实现URL重写。
1.3Rewrite实际场景
- 在Nginx中使用Rewrite实现跳转有以下三种场景:
- 直接使用rewrite进行匹配跳转(主要匹配的是具体路径)
- 使用if匹配全局变量后跳转
- 使用location匹配再跳转(可以匹配后执行proxy_pass,跳转到其他服务上)
所以rewrite语句只允许放在server{},if{},location{}段中,其中location只对域名后面的出去传递参数外的字符串起作用。
- 对域名或参数字符串
使用if全局变量配置
使用proxy_pass反向代理
1.4Nginx正则表达式
常用的正则表达式元字符
字符 | 说明 |
---|---|
^ | 匹配输入字符串的起始位置 |
$ | 匹配输入字符串的结束位置 |
* | 匹配前面的字符零次或多次 |
+ | 匹配前面的字符一次或多次 |
. | 匹配除“\n”之外的任何单个字符 |
\ | 将后面接着的字符标记为一个特殊字符或一个原义字符或一个向后引用 |
\d | 匹配纯数字 |
{n} | 重复n次 |
{n,} | 重复n次或更多次 |
[c] | 匹配单个字符c |
[a-z] | 匹配a-z小写字母的任意一个 |
[a-zA-Z] | 匹配a-z小写字母或A-Z大写字母的任意一个 |
() | 表达式的开始和结束位置 |
? | 匹配前面的字符零次或者一次 |
\w | 匹配字母或者数字或者下划线或者汉字 |
\s | 匹配任意的空白符 |
\b | 匹配单词的开始或结束 |
1.5Rewrite命令语法
rewrite <正则> <跳转后的内容> [rewrite支持的flag标记];
- flag标记说明
标记 | 说明 |
---|---|
last | 相当于Apache的[L]标记,表示完成rewrite |
break | 本条规则匹配完成即终止,不再匹配后面的任何规则 |
redirect | 返回302临时重定向,浏览器地址显示跳转后的URL地址,爬虫不会更新url |
permanent | 返回301永久定向,浏览器地址栏会显示跳转后的URL地址,爬虫更新url |
1.6执行顺序
按顺序叙述
- 执行server模块里面的rewrite指令。
- 执行选定的location中的rewrite指令。
- 执行选定的location中if中的rewrite指令
2.location分类
- location = patt {} [精准匹配]
- location patt {} [一般匹配]
- location ~ patt {} [正则匹配]
2.1正则匹配的常用表达式
= | 进行普通字符精准匹配,也就是完全匹配 |
---|---|
^~ | 表示普通字符匹配,如果匹配成功,则不再匹配其他location |
~ | 区分大小写的匹配 |
~* | 不区分大小写的匹配 |
!~ | 区分大小写的匹配取非 |
!~* | 不区分大小写的匹配取非 |
@ | 定义一个location,使用再内部定向的时候 |
2.2location优先级
- 相同类型的表达式,字符串长的会优先匹配
- 按优先级排列
= 类型
^~类型表达式
正则表达式( ~ 和 ~*)类型
常规字符串匹配类型,按前缀匹配
通用匹配( / ),如果没有其他匹配,任何请求都会匹配到
2.3location优先级规则
- 匹配某个具体文件
(location = 完整路径)>(location ^~ 完整路径)>(location ~* 完整路径)>(location ~ 完整路径)>(location 完整路径)>(location /) - 用目录做匹配访问某个文件
(location = 目录)>(location ^~ 目录)>(location ~ 目录)>(location ~* 目录)>(location 目录)>(location /)
2.4比较rewrite和location
- 相同点
都能够实现跳转 - 不同点
rewrite是在同一域名内更改获取资源的路径
location是对一类路径做控制访问或反向代理,还可以proxy_pass到其他机器 - rewrite会卸载location里,执行顺序
执行server里面的rewrite指令
执行location匹配
执行选定的location中的rewrite指令
2.5实际网站中,至少有三个匹配规则定义
-
第一个必选规则:直接匹配网站根,通过域名访问首页比较频繁,使用这个会加速处理,比如官网。
-
第二个必选规则是处理静态文件请求,这是nginx作为http服务器的强项,有两种配置模式,目录匹配或后缀匹配,任选其一或搭配使用
-
第三个规则就是通用规则,比如用来转发带 .php 、.jsp后缀的动态请求到后端应用服务器,非静态文件请求就默认是动态请求。
3.配置:基于域名的跳转
现在公司旧域名因为有业务需求变更,使用新域名代替,但是旧域名不能废除,就需要跳转到新域名上,并且可以访问到旧域名发布的内容
[root@server]# vim /etc/hosts //添加映射旧域名与新域名
[root@server nginx-1.15.9]# mkdir -p /var/log/nginx //创建日志文件
[root@server nginx-1.15.9]# vim /usr/local/nginx/conf/nginx.conf //配置主配置文件
测试访问www.jerry.com会自动跳转到www.tom.com
同时访问www.jerry.com/.1.html在显示错误错误界面同时可以看到域名也会变化为www.tom.com/.1.html
4.基于客户端IP访问跳转
如果业务新版本上线,所有的IP访问任何内容都显示维护页面,只有公司的IP能够访问
[root@localhost ~]# vim /usr/local/nginx/conf/nginx.conf
[root@localhost ~]# mkdir -p /var/www/html //创建返回维护显示页面
[root@localhost ~]# cd /var/www/html
[root@localhost html]# vim weihu.html
<h1>Under maintenance</h1>
[root@localhost ~]# systemctl restart nginx.service //重启服务
在服务端可以访问
在客户端windows中访问(添加映射,也可使用域名访问)
- 使用ip访问
- 使用域名访问
5.基于旧域名跳转到新域名后面家目录
当访问www.jerry.com/post/1.html时会自动跳转到www.tom.com/post/1.html
[root@www ~]# vim /etc/hosts //添加映射
[root@www ~]# mkdir -p /usr/local/nginx/html/bbs/post //创建家目录
[root@www ~]# echo "<h1> this is 1.html <h1>" >> /usr/local/nginx/html/bbs/post/1.html //网页显示内容
[root@www ~]# vim /usr/local/nginx/conf/nginx.conf
访问旧域名会自动跳转到指定的家目录
6.基于参数匹配(多余的)的跳转
访问http://www.jerry.com/100- (100|200) -100.html会跳转到http://www.jerry.com的页面
[root@www ~]# vim /usr/local/nginx/conf/nginx.conf
[root@www ~]# systemctl restart nginx //重启服务
7.基于目录下所有php结尾的文件跳转
要求访问http://www.jerry.com/upload/123.php跳转到首页www.jerry.com (场景:注册)
[root@www ~]# vim /usr/local/nginx/conf/nginx.conf
[root@www ~]# systemctl restart nginx
并不需要.php这个文件,也可以显示
8.基于最普通一条uri请求的跳转
[root@www ~]# vim /usr/local/nginx/conf/nginx.conf
[root@www ~]# systemctl restart nginx
总结
- rewrite和location功能有点像,都能实现跳转。主要区别在于rewrite是在同一域名内更改获取资源的路径,而location是对一类路径做控制访问或反向代理,可以proxy_pass到其他机器。
- 下面是可以用作if判断的全局变量
- $content_type : 请求头中的Content-Type字段。
- $document_root : 当前请求在root指令中指定的值。
- $host : 请求主机头字段,否则为服务器名称。
- $http_user_agent : 客户端agent信息
- $http_cookie : 客户端cookie信息
- $limit_rate : 这个变量可以限制连接速率。
- $request_method : 客户端请求的动作,通常为GET或POST。
- $remote_addr : 客户端的IP地址。
- $remote_port : 客户端的端口。
- $remote_user : 已经经过Auth Basic Module验证的用户名。
- $request_filename : 当前请求的文件路径,由root或alias指令与URI请求生成。
- $scheme : HTTP方法(如http,https)。
- $server_protocol : 请求使用的协议,通常是HTTP/1.0或HTTP/1.1。
- $server_addr : 服务器地址,在完成一次系统调用后可以确定这个值。
- $server_name : 服务器名称。
- $server_port : 请求到达服务器的端口号。
- $request_uri : 包含请求参数的原始URI,不包含主机名,如:”/foo/bar.php?arg=baz”。
- u r i : 不 带 请 求 参 数 的 当 前 U R I , uri : 不带请求参数的当前URI, uri:不带请求参数的当前URI,uri不包含主机名,如”/foo/bar.html”。
- d o c u m e n t u r i : 与 document_uri : 与 documenturi:与uri相同。