概要:
在 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;
}
}
验证步骤
- 重载 Nginx 配置:reload nginx
-
访问静态资源并查看响应头:

预期输出应包含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