Nginx高级配置

条件符号

符号 作用
= 比较变量、字符串是否相等,相等为true、不等则为false
!= 比较变量、字符串是否不相等,不相等为true、相等为false
~ 区分大小写的正则匹配,匹配上为true,否则为false
!~ 区分大小写的正则匹配,不匹配上为true,否则为false
~* 不区分大小写的正则匹配,匹配上为true,否则为false
!~* 不区分大小写的正则匹配,不匹配上为true,否则为false

条件参数

符号 作用
-f 和 !-f 请求的文件是否存在
-d 和 !-d 判断的目录是否存在
-e 和 !-e 判断的文件、目录、软连接是否存在
-x 和 !-x 判断的请求文件是否有有执行权限

if指令

1.if语句,用于条件判断,根据判断结果的不同,执行不同的动作,if写在server{}或者location{}标签里。
# 比如针对用户的请求客户端判断,或者针对用户的ip地址判断
# 基于nginx的内置变量就可以提取出这些信息。。
if (匹配条件) {
执行动作
}

匹配条件
- nginx内置变量
- 使用nginx的if提供的条件判断符号,等于不等于....
server {
listen 22555;
server_name localhost;
root html;
charset utf-8;

location  /test-if {
   # 客户端类型完全匹配到 huawei
   if ($http_user_agent = huawei){
       echo "agent is huawei";
   }

   # 客户端类型区分大小写
   # 你这里的正则符号,就是一个完全的字符 ,区分大小写的字符串
   # Iphone ,你只能传入 Iphone才行
   # 基于正则匹配,你得写入正则符号。
   if ($http_user_agent ~ Iphone) {
       echo "agent is Iphone";
   }

   # 客户端类型不区分大小写
   if ($http_user_agent ~* Chrome) {
       echo "agent is Chrome";
   }

   # 如果请求方法不是GET就提示 ”只能用GET方法,你这个烂玩家“
   if ($request_method != GET) {
       echo "必须是GET方法,你这个烂玩家";
   }

   # 如果是IE浏览器,直接提示 "不支持IE,请下载Chrome浏览器"
   # 不区分大小写的正则匹配
   if ($http_user_agent ~* IE){
       echo "不支持IE,请下载Chrome浏览器";
   }

   # 如果上面没有任何匹配,执行如下语句
   echo  "if规则没有匹配到";
   echo "agent is  >>>>>>     $http_user_agent";
   echo "request_method is  >>>>>>>>  $request_method";
}

}
测试完全匹配,基于useragent精确匹配到字符串huawei
curl -A 'user-agent的字符串信息'    url

curl 10.0.0.8:22555/test-if
if规则没有匹配到
agent is  >>>>>>     curl/7.29.0
request_method is  >>>>>>>>  GET

[root@master-61 ~]#curl -A 'huawei-mate40' 10.0.0.8:22555/test-if
if规则没有匹配到
agent is  >>>>>>     huawei-mate40
request_method is  >>>>>>>>  GET

[root@master-61 ~]#curl -A 'Huawei' 10.0.0.8:22555/test-if
if规则没有匹配到
agent is  >>>>>>     Huawei
request_method is  >>>>>>>>  GET

[root@master-61 ~]#curl -A 'huawei' 10.0.0.8:22555/test-if
agent is huawei
测试区分大小的 Iphone

[root@master-61 ~]#curl -A 'iphone' 10.0.0.8:22555/test-if
if规则没有匹配到
agent is  >>>>>>     iphone
request_method is  >>>>>>>>  GET

[root@master-61 ~]#curl -A 'Iphone' 10.0.0.8:22555/test-if
agent is Iphone

[root@master-61 ~]#curl -A 'IPhone' 10.0.0.8:22555/test-if
if规则没有匹配到
agent is  >>>>>>     IPhone
request_method is  >>>>>>>>  GET
测试不区分大小写的正则匹配

[root@master-61 ~]#curl -A 'windows xxxxx chrome xxxxx' 10.0.0.8:22555/test-if
agent is Chrome

[root@master-61 ~]#curl -A 'windows xxxxx CHroME xxxxx' 10.0.0.8:22555/test-if
agent is Chrome

[root@master-61 ~]#curl -A 'windows xxxxx CHroMxE xxxxx' 10.0.0.8:22555/test-if
if规则没有匹配到
agent is  >>>>>>     windows xxxxx CHroMxE xxxxx
request_method is  >>>>>>>>  GET
测试指定请求方法
如果你给 10.0.0.8:22555/test-if 发送的请求方式不是GET,就会进入如下的 if条件区域

[root@master-61 ~]#curl -X POST 10.0.0.8:22555/test-if 
必须是GET方法,你这个烂玩家

[root@master-61 ~]#curl -X PUT  10.0.0.8:22555/test-if 
必须是GET方法,你这个烂玩家

[root@master-61 ~]#curl -X DELETE  10.0.0.8:22555/test-if 
必须是GET方法,你这个烂玩家

return指令

return 可以用于 server {} ;  location {} ; if {};

return用于返回状态码以及文本等
return code [text];
或者用于返回如状态码和跳转url
return code url;
或者跳转url
return url;

return之后的命令不会再执行。
server {
listen 22666;
server_name _;
root html;

# 精确匹配,客户端只访问了网页根目录
location  = / {
   echo "welcome to chaoge linux course.";
}

location /test-return {
       # 客户端完全匹配
       if ($http_user_agent = huawei){
         return 200 "agent is  $http_user_agent \n";
       }

       # 限制必须是GET方法
       if ($request_method != GET){
         return 405 "必须是GET方法!其他方法不允许\n";
       }

       # 如果是IE浏览器,就重定向
       if ($http_user_agent ~* IE){
         return 301 http://yuchaoit.cn/cai.jpg;
       }

       # 没有if条件匹配到
       return 404 "sorry, nothing ....\n";
   }
 # 默认匹配,如果没有匹配到任意内容,跳转到首页 jd.com就是这个做法
 location / {
   	return 301 http://yuchaoit.cn/cai.jpg;
   }
 location /ji {
       return 500 "鸡你太美\n";
   }
}

set指令

set就是用于设置一个nginx变量,这个值可以是文本、变量或者其组合。

set可以用于设置server{}  location{}  if{}

set 变量名 变量值;
server {
listen 22777;
server_name _;
root html;

set $my_url http://yuchaoit.cn/cai.jpg;

location /test-set {
   return 301 $my_url;
}
}

break指令

break用于终止所在区域的后续指令,且只针对ngx_http_rewrite_module提供的模块指令;
也就是咱们目前所学的这几个rewrite相关的指令,在break后面不会执行了。

break可以用于
server{}
location{}
if{}
server {
   listen 22888;
   server_name _;
   root html;

   location / {
       set $my_website yuchaoit.cn;
       echo "welcome to my website:" $my_website;
       break;
       set $my_name yuchao;
       echo "my name is" $my_name;
   }
}

执行结果
curl 10.0.0.9:22888
welcome to my website: yuchaoit.cn
发现break后续的 set指令并未正确执行。

rewrite指令

1. rewrite指令可以基于用户的请求url,再通过正则表达式的匹配情况,进行地址重写;
2. rewrite指令可以写多条,按照顺序依次执行;
3. rewrite指令可以根据flag标记进行进一步处理(last、break、redirect、permanent)
flag参数解释:
last
停止处理当前的 ngx_http_rewrite_module指令集,向下匹配新的locaiton URI规则;

break
ngx_http_rewrite_module与break指令一样, 停止处理当前的指令集 ;

redirect(公司的域名临时更换)
返回带有 302 代码的临时重定向;
如果替换字符串不以“ http://”、“ https://”或“ $scheme”开头,则使用该字符串;
浏览器将显示跳转后的url地址,且浏览器不会做dns缓存记录;

permanent(公司域名永久更换,老域名还在运行)
返回带有 301 代码的永久重定向。
浏览器会记录跳转后的dns缓存,浏览器显示跳转后的url。

参数应用说明:
1.设置redirect、permanent参数,浏览器都会更改为跳转后的url,是由服务器返回新的URL,客户端对这个URL重新发起了请求。
2.设置last和break参数,浏览器依然显示原本的URL,由于服务器内部完成跳转。
3.last和break区别:
last在标记完本次规则匹配完成后,对其所在的server{}标签重新发起修改后的URL请求,再次匹配location{}。
break是在本条规则匹配完毕后,终止匹配,不再匹配后面的location{};

redirect和permanent实战

HTTP协议规范里,301是永久重定向、302是临时重定向。

permanent

要求
www.pythonav.cn
↓
www.yuchaoit.cn
状态码为301.

旧网站配置
# 注意要做好本地dns解析
10.0.0.9 www.pythonav.cn www.yuchaoit.cn

# 1.创建测试数据
mkdir -p /pythonav
echo "i am pythonav " > /pythonav/index.html

# 2.配置文件
cat /etc/nginx/conf.d/pythonav.conf 
server {
listen 80;
server_name www.pythonav.cn;
location / {
   root /pythonav/;
   index index.html;
   rewrite /  http://www.yuchaoit.cn permanent;
}
}

# 3.重加载
nginx -s reload


新网站配置文件
# 1.创建测试数据
mkdir -p /www.yuchaoit.cn/
echo 'i am www.yuchaoit.cn' > /www.yuchaoit.cn/index.html

# 2.配置文件
vim www.yuchaoit.cn.conf 
server {
listen 80;
server_name www.yuchaoit.cn;
location / {
   root /www.yuchaoit.cn/;
   index index.html;
}
}

# 3.重加载
nginx -s reload

redirect

要求
www.yuchaoit.cn/phone  旧域名
↓
party.yuchaoit.cn
状态码302

旧网站配置
vim www.yuchaoit.cn.conf 
server {
listen 80;
server_name www.yuchaoit.cn;
location / {
   root /www.yuchaoit.cn/;
   index index.html;
rewrite / http://party.yuchaoit.cn redirect;
}
}

# 让用户去访问 www.laoliulinux.cc/phone
自动跳转到http://phone.laoliulinux.cc这个新域名

新的活页页面网站
# 1.创建测试数据
mkdir -p /party.yuchaoit.cn/
echo 'i am party.yuchaoit.cn' > /party.yuchaoit.cn/index.html

# 2.配置文件
server {
listen 80;
server_name party.yuchaoit.cn;
location / {
   root /party.yuchaoit.cn/;
   index index.html;
}
}

# 3.重加载
nginx -s reload

last

可以从 location {}  >  location {}  > location {}
多次匹配。

访问AAA、重写到BBB、重写到CCC,且是服务器内部跳转。

访问AAA,服务器内部跳转BBB,最后跳转到CCC

# 创建测试数据,用于查看url内部跳转效果,以及保持了url的参数

# 1.创建测试数据
mkdir -p /linux0224/
echo 'i am ccc,  how are you ~~~' > /linux0224/hello.html

# 2.配置文件
server {
listen 30000;
server_name _;

location /CCC {
   alias /linux0224/;
}

location /BBB {
   rewrite ^/BBB/(.*)$ /CCC/$1 last;
}

location /AAA {

   rewrite ^/AAA/(.*)$ /BBB/$1 last;
}
}

break

break是在本条规则匹配完毕后,终止匹配,不再匹配后面的location{};

表示中断匹配,访问到AAA资源后,只rewrite跳转一次,终止后续的跳转。

# 创建测试数据,用于查看url内部跳转效果,以及保持了url的参数

mkdir -p /www/{AAA,BBB,CCC}
echo 'AAA' > /www/AAA/index.html
echo 'BBB' > /www/BBB/index.html
echo 'CCC' > /www/CCC/index.html

server {
listen 31000;
server_name _;

#
location /CCC {
   root /www/;
   index index.html;
}

location /BBB {
 root /www/;
   index index.html;
   rewrite ^/BBB/(.*)$ /CCC/$1 last;
}

location /AAA {
   root /www/;
   index index.html;
   rewrite ^/AAA/(.*)$ /BBB/$1 break;
}

}
posted @ 2023-08-31 11:51  村尚chun叔  阅读(43)  评论(0编辑  收藏  举报