nginx if指令

一、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

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注