nginx的安装、启动关闭退出重启基本操作命令、nginx.conf配置文件了解、location的root、alias、proxy系列的数据都已经写过了,有兴趣了解的可以看看文末推荐文章。location里面的东西真的很多,也是非常重要的。可以说在配置nginx过程中90%都是在配置location。这一篇文章的目的是写location中的另一个重要部分rewrite,以及内部使用到的if判断语句。废话不多说,开干。
1. rewrite规则
rewrite通过正则表达式来匹配location命中的请求,然后根据重定向的url信息和rewrite的flag标识位属性,完成一次完整的重定向操作。
1.1 rewrite语法格式
rewrite语法格式如下:
rewrite <regex> <replacement> [flag]
rewrite:重定向命令regex:必填,正则表达式replacement:必填,重定向的url信息flag:非必填,其对应的值由4个,分别是last、break、redirect、permanent。
1.2 flag标志位
flag标识有4个值,下面来一起认识认识这4个值的具体含义和作用。
last:会引发location的重新匹配,这个重新匹配是根据replacement来实现的。存在一个致命的确定就是可能引起死循环,需要谨慎使用。#1 使用last标志位实现重定向 location /itcrud { rewrite ^/ /it/crud/ last; } #2 模拟上面location重定向命中的目标location location /it { root /usr/local/; index it.html; }地址栏请求:
http://172.16.156.131/itcrud(ip地址是虚拟机的地址,测试用)响应返回显示的是
it.html页面信息。注意:这里的
/it/crud/是后面带上/,地址栏上的地址不会变化,当把/去掉,就会出现请求响应变为301,重定向到http://172.16.156.131/it/crud,然后响应返回显示it.html页面。所以说last是内部重定向不是完全正确的。刚才说
last容易造成死循环,为什么呢?现在把#2修改一下。修改如下:location /it { rewrite ^/ /itcrud; root /usr/local/; index it.html; }再次请求
http://172.16.156.131/itcrud出现的就是500错误,打开nginx的错误日志会提示redirection cycle。break:完成该rewrite规则的执行后,停止处理后续rewrite指令集,并不再重新查找;但是当前location内剩余非rewrite语句和location外的的非rewrite语句可以执行。# 使用break标志位实现重定向 location /itcrud { rewrite ^/ /it/crud/ break; # 注意我这里使用的是“/it/crud/” }这个时候在浏览器上输入
http://172.16.156.131/itcrud,会通过内部重定向进入到nginx目录下的html/it/crud目录中找index.html文件并响应。这里存在和
last的同样问题,如果将/it/crud/换成/it/crud,结果就变成301返回,浏览器地址会变化成http://172.16.156.131/it/crud。redirect:返回302临时重定向,地址栏会显示跳转后的地址。#1 使用break标志位实现重定向 location /itcrud { rewrite ^/ /it/crud/ redirect; } #2 location /it { root /usr/local/; }地址栏请求:
http://172.16.156.131/itcrud返回
302重定向,给出的重定向地址是http://172.16.156.131/it/crud。浏览器重新请求新地址,命中#2获取对应的页面信息。permanent:返回301永久重定向,地址栏会显示跳转后的地址;即表示如果客户端不清理浏览器缓存,那么返回的结果将永久保存在客户端浏览器中了。#1 location /itcrud { rewrite ^/ /it/cc permanent; } #2 location /it { root /usr/local/; }这个基本和
redirect是相同的,不同的就是在于状态码上面。redirect和permanent两种方式不会受replacement位置值末尾是否有/影响。
2. if条件
nginx里面的if判断不是很复杂,就从格式来说。看基本格式:
#1 正则匹配
if(变量 操作符 正则表达式){
# 做对应的操作
}
# 文件、目录匹配
if(操作符 变量){
# 做相应的操作
}
就是这么一个简单的格式,没有else代码块,没有and、or、||、&&等连接符。
变量:一般取的是全局变量或者自定义设定的变量,如下:
location /{ set $a = "1"; set $flag = false; if($a = "1"){ # 自定义变量:a set $flag = true; } if($http_referer = "http://blog.itcrud.com"){ # 全局变量:http_referer set $flag = true; } }全局变量有很多,比较常用的在之前的博客已经写过,可以参考:nginx基础学习(一):linux环境下nginx的安装和配置文件的初步认识
操作符:上面的if判断语句括号内的格式有两种,对应的操作符也就不同。
正则匹配:
=:等值比较;~:与指定正则表达式模式匹配时返回“真”,判断匹配与否时区分字符大小写;~*:与指定正则表达式模式匹配时返回“真”,判断匹配与否时不区分字符大小写;!~:与指定正则表达式模式不匹配时返回“真”,判断匹配与否时区分字符大小写;!~*:与指定正则表达式模式不匹配时返回“真”,判断匹配与否时不区分字符大小写。文件和目录匹配:
-f,!-f:判断指定的路径是否为存在且为文件;-d,!-d:判断指定的路径是否为存在且为目录;-e,!-e:判断指定的路径是否存在,文件或目录均可;-x,!-x:判断指定路径的文件是否存在且可执行。
正则表达式:没啥说的,因为内容太多,可以找度娘找专门的文章学习。