一、if 指令的基本结构
nginx复制下载
if (条件) {
# 条件成立时执行的配置
}
使用位置:server 块或 location 块内
二、条件判断类型
1. 正则表达式匹配
| 操作符 | 含义 | 示例 |
|---|
~ | 区分大小写匹配 | if ($http_user_agent ~ "Chrome") |
~* | 不区分大小写匹配 | if ($http_user_agent ~* "mobile") |
!~ | 区分大小写不匹配 | if ($http_user_agent !~ "bot") |
!~* | 不区分大小写不匹配 | if ($http_user_agent !~* "spider") |
2. 文件及目录判断
| 操作符 | 含义 | 示例 |
|---|
-f | 文件存在 | if (-f $request_filename) |
!-f | 文件不存在 | if (!-f $request_filename) |
-d | 目录存在 | if (-d $request_filename) |
!-d | 目录不存在 | if (!-d $request_filename) |
-e | 文件或目录存在 | if (-e $request_filename) |
!-e | 文件或目录不存在 | if (!-e $request_filename) |
-x | 文件可执行 | if (-x $request_filename) |
!-x | 文件不可执行 | if (!-x $request_filename) |
3. 变量比较
| 操作符 | 含义 | 示例 |
|---|
= | 等于 | if ($request_method = POST) |
!= | 不等于 | if ($remote_addr != 127.0.0.1)
|
三,正则表达式与文件匹配实例
一、正则表达式匹配实例
实例1:区分大小写匹配 ~
# 只匹配 .JPG 大写后缀
location ~ \.JPG$ {
return 200 "这是大写JPG文件";
}
# 访问 /logo.JPG → 匹配 ✅
# 访问 /logo.jpg → 不匹配 ❌
实例2:不区分大小写匹配 ~*
# 匹配所有图片文件,不区分大小写
location ~* \.(jpg|jpeg|png|gif)$ {
return 200 "这是图片文件";
}
# 访问 /logo.JPG → 匹配 ✅
# 访问 /logo.jpg → 匹配 ✅
# 访问 /logo.PNG → 匹配 ✅
实例3:不匹配 !~
# 不是 .php 结尾的才处理
location / {
if ($request_uri !~ \.php$) {
return 200 "不是PHP文件";
}
}
# 访问 /index.html → 匹配 ✅
# 访问 /index.php → 不匹配 ❌
实例4:不区分大小写不匹配 !~*
# 排除所有图片文件
location / {
if ($request_uri !~* \.(jpg|png|gif)$) {
return 200 "不是图片文件";
}
}
# 访问 /index.html → 匹配 ✅
# 访问 /logo.JPG → 不匹配 ❌
# 访问 /logo.png → 不匹配 ❌
二、文件及目录匹配实例
实例5:判断文件是否存在 -f / !-f
location /download/ {
alias /data/files/;
# 文件不存在时返回404
if (!-f $request_filename) {
return 404 "文件不存在";
}
# 文件存在时正常下载
}
实例6:判断目录是否存在 -d / !-d
location / {
root /var/www/html;
# 如果是目录,尝试找 index.html
if (-d $request_filename) {
rewrite ^(.*)/$ $1/index.html last;
}
# 如果不是目录,可能是文件
if (!-d $request_filename) {
add_header X-File "直接访问文件";
}
}
实例7:判断文件或目录是否存在 -e / !-e
location / {
root /var/www/html;
# 如果文件或目录都不存在,转给 PHP 处理
if (!-e $request_filename) {
rewrite ^(.*)$ /index.php?path=$1 last;
}
}
实例8:判断文件是否可执行 -x / !-x
location /cgi-bin/ {
alias /usr/lib/cgi-bin/;
# 文件不可执行时拒绝访问
if (!-x $request_filename) {
return 403 "文件无执行权限";
}
# 可执行文件正常处理
proxy_pass http://cgi_backend;
}
三、组合实例
实例9:防盗链(正则+文件判断)
location ~* \.(jpg|png|gif)$ {
# 检查文件是否存在
if (!-f $request_filename) {
return 404;
}
# 防盗链
valid_referers none blocked example.com;
if ($invalid_referer) {
return 403;
}
}
实例10:URL 重写+文件判断
location / {
# 将 /user/123 重写为 /profile.php?id=123
if ($request_uri ~ ^/user/(\d+)/?$) {
set $user_id $1;
rewrite ^ /profile.php?id=$user_id last;
}
# 检查文件是否存在,不存在则转给 index.php
if (!-e $request_filename) {
rewrite ^ /index.php last;
}
}
实例11:移动端跳转(正则匹配)
location / {
# 检测移动端 UA(不区分大小写)
if ($http_user_agent ~* "(mobile|iphone|android)") {
rewrite ^(.*)$ /mobile/$1 last;
}
}
实例12:目录不存在时创建
location /upload/ {
alias /data/upload/;
# 如果目录不存在,返回特定提示
if (!-d $request_filename) {
return 404 "上传目录不存在";
}
# 检查文件是否可写
if (!-w $request_filename) {
return 403 "文件不可写";
}
}
四、常用组合速查表
| 场景 | 表达式 | 作用 |
|---|
| 图片防盗链 | ~* \.(jpg|png)$ | 匹配所有图片 |
| 排除PHP | !~ \.php$ | 不是PHP文件 |
| 文件不存在 | !-f $request_filename | 文件不存在时处理 |
| 目录不存在 | !-d $request_filename | 目录不存在时处理 |
| 路径不存在 | !-e $request_filename | 文件和目录都不存在 |
| 检查可执行 | -x $request_filename | 文件可执行 |
| 移动端检测 | ~* "(mobile|android)" | 匹配移动端 UA |
| 爬虫检测 | ~* "(bot|spider)" | 匹配爬虫 UA |
发表回复