Nginx详解(三):ngx_http_rewrite_module模块核心指令详解

概要:

在 Nginx 的众多功能模块中,ngx_http_rewrite_module是实现请求动态处理的核心组件,它通过一系列指令实现 URI 重写、条件判断、响应返回等功能。本文将以 CentOS 7.9 环境为例(主机名www.a.com,IP 172.25.0.100,网站数据目录 /data/sitea/),详细解析break、if、return、rewrite、set五大指令的使用方法,并提供完整的配置验证流程。

环境准备与配置规范

基础环境搭建

在 CentOS 7.9 系统中,首先需要完成 Nginx 的安装与基础配置:

bash 复制代码
# 安装Nginx

sudo yum install -y nginx

# 创建网站数据目录

sudo mkdir -p /data/sitea/{html,static,mobile,api/v1,api/v2}

# 准备测试文件

sudo echo "SiteA Home" > /data/sitea/html/index.html

sudo echo "Mobile Version" > /data/sitea/html/mobile/index.html

sudo touch /data/sitea/static/style.css

sudo echo "API V1" > /data/sitea/api/v1/test.txt

sudo echo "API V2" > /data/sitea/api/v2/test.txt

sudo echo "API root index" > /data/sitea/api/index.html

# 创建虚拟主机配置文件

sudo mkdir -p /etc/nginx/conf.d/vhosts

sudo nano /etc/nginx/conf.d/vhosts/a.com.conf

基础虚拟主机配置

a.com.conf中添加基础配置:

bash 复制代码
server {
    listen 80;
    server_name www.a.com;
    root /data/sitea/html;
    index index.html;
    
    location /static/ {
        root /data/sitea;
    }
    
    location /api/ {
        root /data/sitea;
    }
}

环境验证

完成基础配置后,通过以下命令验证环境:

bash 复制代码
# 检查配置语法

nginx -t

# 重载Nginx配置

nginx -s reload

# 测试访问(需在客户端修改hosts文件添加172.25.0.100 www.a.com)

curl http://www.a.com

# 应返回"SiteA Home"

break 指令:终止请求处理流程

指令语法与作用

break指令用于立即终止当前location或server块内的后续指令执行,不再进行 URI 重写或位置匹配,语法非常简单:

break;

典型应用场景

  • 静态资源路径直接响应,避免执行多余逻辑
  • 条件判断后提前终止请求处理

实战配置示例

在静态资源路径中添加break指令:

bash 复制代码
server {
    listen 80;
    server_name www.a.com;
    root /data/sitea/html;
    index index.html;

    location /static/ {
        root /data/sitea;
        expires 30d;
        break;
        invalid_directive;
    }

    location /api/ {
        root /data/sitea;
    }
}

验证步骤

  1. 重载 Nginx 配置:reload nginx
  1. 访问静态资源并查看响应头:

    curl -I http://www.a.com/static/style.css

预期输出应包含Expires字段,且由于break指令的存在,该location内的其他错误指令不会影响执行(可故意添加错误指令测试)。

if 指令:条件判断的核心工具

语法与条件类型

if指令通过条件表达式控制请求处理流程,语法为:

复制代码
if (condition) { ... }

if (condition) { ... }

条件满足时,执行配置块中的配置指令; server, location

condition:

比较操作符:

= 相同 != 不同

~ 模式匹配,区分字符大小写

~* 模式匹配,不区分字符大小写

!~ 模式不匹配,区分字符大小写

!~* 模式不匹配,不区分字符大小写

文件及目录存在性判断:

-e, !-e 存在与否( 包括文件,目录,软链接)

-f, !-f 文件 -d, !-d 目录 -x, !-x 执行

支持的条件类型包括:

  • 变量判空:if ($variable)(变量值为空或 "0" 时为假)
  • 字符串比较:if (variable = value) 或 if (variable != value)
  • 正则匹配:if (variable \~ pattern)(区分大小写)、if (variable ~* pattern)(不区分大小写)
  • 文件检查:if (-f filename)(文件存在)、if (-d dirname)(目录存在)等

return 指令:快速返回响应结果

指令语法与功能

return指令用于直接返回 HTTP 状态码和响应内容,终止请求处理,语法为:

复制代码
return code [text|url];

典型应用场景

  • 域名重定向(301/302)
  • 禁止特定 IP 访问(403)
  • 维护模式返回(503)

应用场景实例

bash 复制代码
server {
    listen 80 default_server;
    server_name www.a.com;
    root /data/sitea/html;
    index index.html;

    access_log /var/log/nginx/access-www.a.com.log main;

    # 首页:移动端跳转逻辑
    location = / {
        if ($http_user_agent ~* "android|iphone") {
            return 302 /mobile/;
        }
        try_files $uri $uri/ /404.html;
    }

    # 静态资源
    location /static/ {
        root /data/sitea;
    }

    # API 路由,并检查 id 参数格式
    location /api/ {
        root /data/sitea;

        set $invalid_id 0;

        if ($arg_id ~ ".+") {
            set $invalid_id 1;
        }
        if ($arg_id ~ ^\d+$) {
            set $invalid_id 0;
        }

        if ($invalid_id = 1) {
            return 400 "Invalid ID Format";
        }
    }

    # 移动页面
    location /mobile/ {
        root /data/sitea/html;
        index index.html;
    }

    # 其他路径 fallback
    location / {
        try_files $uri $uri/ /404.html;
    }
}
复制代码

验证方法

bash 复制代码
curl -I http://www.a.com/            # 应该返回 200 页面为

curl http://www.a.com/               # 页面显示"SiteA Home"

curl -I -H "User-Agent: iPhone" http://www.a.com/   #跳转移动端页面 返回302

curl http://www.a.com/api/?id=abc    # 应该返回 400

curl http://www.a.com/api/?id=123    # 应该返回 200

curl http://www.a.com/mobile/        # 应该返回 index.html

curl http://www.a.com/maintenance=1  # 返回500 最终显示404

rewrite 指令:URI 重写的核心能力

rewrite 指令简介

bash 复制代码
​​​​​​​rewrite regex replacement [flag];
  • regex:正则表达式,用来匹配原始 URI;

  • replacement:用于替换的 URI;

  • flag:可选参数,常用有:

    • last:停止 rewrite,重新进入新的 location 匹配流程;

    • break:停止 rewrite,但不重新匹配 location;

    • redirect:返回 302 临时重定向;

    • permanent:返回 301 永久重定向。

应用场景配置

bash 复制代码
server {
    listen 80 default_server;
    server_name www.a.com;
    root /data/sitea;
    index index.html index.php;

    access_log /var/log/nginx/access-www.a.com.log main;

    #######################################
    #  301/302 Redirect Rewrite
    #######################################

    # 永久跳转 old-about → about.html
    location = /old-about {
        rewrite ^ /about.html permanent;
    }

    # 临时跳转 beta → static 页面
    location = /beta {
        rewrite ^ /static/beta/index.html redirect;
    }

    #######################################
    #  break 内部 rewrite
    #######################################

    # /doc → /static/docs/index.html,地址栏不变
    location = /doc {
        rewrite ^ /static/docs/index.html break;
    }

    #######################################
    #  首页移动端重定向
    #######################################

    location = / {
        if ($http_user_agent ~* "android|iphone") {
            return 302 /mobile/index.html;
        }
        try_files $uri $uri/ /404.html;
    }

    #######################################
    #  静态资源路径
    #######################################

    location /static/ {
        root /data/sitea;
    }

    #######################################
    #  RESTful API Rewrite
    #######################################

    location ~ ^/api/user/(\d+)$ {
        rewrite ^/api/user/(\d+)$ /api/v1/user.php?id=$1 last;
    }

    location ~ ^/api/product/(\d+)/detail$ {
        rewrite ^/api/product/(\d+)/detail$ /api/v1/product_detail.php?id=$1 last;
    }

    location ~ ^/api/order/(\d+)$ {
        rewrite ^/api/order/(\d+)$ /api/v1/order.php?id=$1 last;
    }

    #######################################
    #  通用 API 入口 + 参数校验
    #######################################

    location /api/ {
        root /data/sitea;
        index index.php;

        # 参数 id 格式校验
        set $invalid_id 0;
        if ($arg_id ~ ".+") {
            set $invalid_id 1;
        }
        if ($arg_id ~ ^\d+$) {
            set $invalid_id 0;
        }
        if ($invalid_id = 1) {
            return 400 "Invalid ID Format";
        }

        try_files $uri $uri/ /404.html;
    }

    #######################################
    #  移动页面
    #######################################

    location /mobile/ {
        root /data/sitea/html;
        index index.html;
    }

    #######################################
    #  默认 fallback,支持 .html 补全
    #######################################

    location / {
        try_files $uri $uri.html $uri/ /404.html;
    }

    #######################################
    #  PHP 处理 via FastCGI
    #######################################

    location ~ \.php$ {
        root /data/sitea;
        fastcgi_pass unix:/run/php-fpm/www.sock;
        fastcgi_index index.php;
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    }
}

目录结构应如下:

bash 复制代码
/data/sitea/
├── index.html
├── about.html
├── mobile/index.html
├── static/docs/index.html
├── static/beta/index.html
├── api/v1/user.php
├── api/v1/order.php
└── api/v1/product_detail.php
#php文件自行配置
bash 复制代码
测试命令:

# 301 永久跳转
curl -I http://www.a.com/old-about

# 302 临时跳转
curl -I http://www.a.com/beta

# break 内部转向
curl http://www.a.com/doc

# 自动补 .html
curl http://www.a.com/about

# RESTful API
curl http://www.a.com/api/user/123
curl http://www.a.com/api/product/456/detail
curl http://www.a.com/api/order/789
相关推荐
七夜zippoe2 小时前
CANN Runtime任务描述序列化与持久化源码深度解码
大数据·运维·服务器·cann
Fcy6484 小时前
Linux下 进程(一)(冯诺依曼体系、操作系统、进程基本概念与基本操作)
linux·运维·服务器·进程
袁袁袁袁满4 小时前
Linux怎么查看最新下载的文件
linux·运维·服务器
代码游侠4 小时前
学习笔记——设备树基础
linux·运维·开发语言·单片机·算法
Harvey9034 小时前
通过 Helm 部署 Nginx 应用的完整标准化步骤
linux·运维·nginx·k8s
珠海西格电力科技5 小时前
微电网能量平衡理论的实现条件在不同场景下有哪些差异?
运维·服务器·网络·人工智能·云计算·智慧城市
释怀不想释怀6 小时前
Linux环境变量
linux·运维·服务器
zzzsde6 小时前
【Linux】进程(4):进程优先级&&调度队列
linux·运维·服务器
聆风吟º7 小时前
CANN开源项目实战指南:使用oam-tools构建自动化故障诊断与运维可观测性体系
运维·开源·自动化·cann
NPE~8 小时前
自动化工具Drissonpage 保姆级教程(含xpath语法)
运维·后端·爬虫·自动化·网络爬虫·xpath·浏览器自动化