nginx之if、break、last、return、rewrite规则语法
nginx安装路径:
/usr/local/nginx
虚拟主机所在路径:
/usr/local/nginx/conf/vhost/
接下来开始实验:
一.if
nginx的if不支持嵌套、&&和||
逻辑判断符号有:
=,!=, ~, ~*(忽略大小写匹配),!~(不匹配),!~*
!表示相反的意思,*表示忽略大小写。
例如:
访问www.1.com的域名,返回状态码403。
server
{
listen 80;
server_name www.1.com;
index index.html;
root /data/wwwroot/www.1.com;
if ($host = www.1.com)
{
return 403;
}
access_log /tmp/1.log ligen;
}
break和last:
两个指令用法相同,但含义不同,需要放到rewrite规则的末尾,用来控制重写后的链接是否继续被nginx配置执行。
例如:
server
{
listen 80;
server_name www.1.com;
index index.html;
root /data/wwwroot/www.1.com;
rewrite /1.html /2.html;
rewrite /2.html /3.html;
access_log /tmp/1.log ligen;
}
结果:
[[email protected] vhost]# curl -x127.0.0.1:80 www.1.com/1.html
3.html
使用break:
server
{
listen 80;
server_name www.1.com;
index index.html;
root /data/wwwroot/www.1.com;
rewrite /1.html /2.html break;
rewrite /2.html /3.html;
access_log /tmp/1.log ligen;
}
测试:
curl -x 127.0.0.1:80 www.1.com/1.html
2.html
第二个rewrite不执行,last也是一样的。
但是当在location里面时,两者不一样:
例如:
server
{
listen 80;
server_name www.1.com;
index index.html;
root /data/wwwroot/www.1.com;
location /
{
rewrite /1.html /2.html;
rewrite /2.html /3.html;
}
location /2.html
{
rewrite /2.html /4.html;
}
location /3.html
{
rewrite /3.html /4.html;
}
access_log /tmp/1.log ligen;
}
访问 www.1.com/2.html会访问到哪个呢:
curl -x127.0.0.1:80 www.1.com/2.html
4.html
这里有一个概念,精确匹配优先于模糊匹配,虽然location /里面也有/2.html,但是下面的location /2.html更精确。
访问www.1.com/1.html呢:
curl -x127.0.0.1:80 www.1.com/1.html
4.html
访问到的是4.html,那么加入break之后呢:
server
{
listen 80;
server_name www.1.com;
index index.html;
root /data/wwwroot/www.1.com;
location /
{
rewrite /1.html /2.html break;
rewrite /2.html /3.html;
}
location /2.html
{
rewrite /2.html /4.html;
}
location /3.html
{
rewrite /3.html /4.html;
}
access_log /tmp/1.log ligen;
}
访问www.1.com/1.html,结果是什么呢?
curl -x127.0.0.1:80 www.1.com/1.html
2.html
这是因为break会中断请求继续重定向,执行到break,后面的rewrite和后面的location都不会去匹配了,直接去返回客户端了。
那么把break换成last呢:
curl -x127.0.0.1:80 www.1.com/1.html
4.html
当访问到last后,请求会再次重定向,并且是从头在来一次,此时的请求应该是www.1.com/2.html,那它匹配的是location /里面的/2.html呢还是location /2.html呢,看前面我所说的精确匹配,匹配到的是后者。
三.return:
最简单的使用方法是返回状态码,看开头第一个例子。
当访问的请求包含.password或者.shadow时,返回405
server
{
listen 80;
server_name www.1.com;
index index.html;
root /data/wwwroot/www.1.com;
if ( $request_uri ~ "\.password|\.shadow" )
{
return 405;
}
access_log /tmp/1.log ligen;
}
测试:
curl -x127.0.0.1:80 www.1.com/abc/2.password -I
HTTP/1.1 405 Not Allowed
return用法二:
返回字符串、变量或者html代码:
server
{
listen 80;
server_name www.1.com;
index index.html;
root /data/wwwroot/www.1.com;
if ( $request_uri ~ "\.password|\.shadow" )
{
return 403 "error";
}
access_log /tmp/1.log ligen;
}
测试:
curl -x127.0.0.1:80 www.1.com/abc/.password
error
再查看它的状态码是不是403:
curl -x127.0.0.1:80 www.1.com/abc/.password -I
HTTP/1.1 403 Forbidden
四.rewrite规则语法:
格式:rewrite regex replacement {flag}
rewrite配置可以在server、location、以及if里面
regex:匹配的整个表达式,其不会匹配到$host(域名)。
replacement:要跳转的目标url,可以以http://或者https://开头,也可以省略$host,直接写$request_uri部分。
flag:处理行为,包括之前的break、last、rediect(302)、permanent(永久重定向301)。
例如:
当访问www.1.com时,跳转到www.discuz.com(这是我自己搭建的discuz虚拟主机,并不是官网。)
server
{
listen 80;
server_name www.1.com;
index index.html;
root /data/wwwroot/www.1.com;
location /
{
rewrite /(.*) http://www.discuz.com/$1 permanent;
}
access_log /tmp/1.log ligen;
}
测试:
curl -x127.0.0.1:80 www.1.com/22.html
<html>
<head><title>301 Moved Permanently</title></head>
在windows上测试(我在discuz主机根目录下创建了22.html):
cat /data/wwwroot/discuz/22.html
www.discuz.com
上一篇: 安装使用nginx