在 nginx 中,`location` 块通过 `rewrite` 指令实现请求重写。核心做法是在匹配的 `location` 内使用 `rewrite regex replacement flag;` 语法,将 uri 与正则表达式匹配并替换为指定路径,配合 `last` 或 `break` 标志控制后续处理流程。

如何配置 location 以捕获特定 URL 模式
要捕获特定 URL 模式,需在 `server` 块内定义 `location`,并使用正则表达式修饰符 `~`(区分大小写)或 `~*`(不区分大小写)。例如,`location ~ ^/old/(.*)$ { ... }` 会匹配所有以 `/old/` 开头的请求,并将剩余部分捕获到反向引用 `$1` 中。这是执行重写的先决条件。

server {
listen 80;
server_name example.com;
# 匹配 /old/page 并重写到 /new/page
location ~ ^/old/(.*)$ {
rewrite ^/old/(.*)$ /new/$1 last;
}
}
上述配置中,当用户访问 /old/article 时,Nginx 进入该 location,执行 rewrite 指令。正则 ^/old/(.*)$ 匹配整个 URI,$1 捕获 article。替换串 /new/$1 生成新 URI /new/article。last 标志表示停止当前 location 的处理,并用新 URI 重新发起内部搜索,可能再次匹配其他 location。
rewrite 标志 last 与 break 的区别是什么
last 和 break 决定了重写后的行为。last 终止当前请求处理,用新 URI 重新进行 location 匹配循环;break 终止当前 location 内的 rewrite 处理,但直接使用新 URI 在当前 location 内继续后续指令(如 proxy_pass),不再重新匹配 location。选择取决于是否希望新 URI 触发新的路由逻辑。

# 使用 break:在新 URI 上直接代理,不重新匹配 location
location ~ ^/api/v1/(.*)$ {
rewrite ^/api/v1/(.*)$ /backend/$1 break;
proxy_pass http://backend_server;
}
# 使用 last:重新匹配,可能进入 /backend/ location
location ~ ^/api/v1/(.*)$ {
rewrite ^/api/v1/(.*)$ /backend/$1 last;
}
在第一个示例中,break 使 URI 变为 /backend/article 后,直接在当前 location 执行 proxy_pass,假设后端服务器能处理此路径。若 backend_server 期望的路径是 /article,则需调整替换串。在第二个示例中,last 导致 Nginx 重新从根开始匹配 URI /backend/article。如果存在 location /backend/ { ... },请求将进入该块,否则可能返回 404 或进入默认 location。这种差异在处理 API 版本迁移或静态资源映射时至关重要。
当 rewrite 规则未生效时如何排查
若 rewrite 未生效,常见原因包括:location 优先级错误、正则表达式未正确转义、标志位使用不当、或缓存导致旧配置生效。首先检查 nginx.conf 语法:nginx -t。其次,启用 access_log 和 error_log 级别为 debug,观察请求处理流程。确认 location 匹配顺序:精确匹配 = > 前缀匹配 ^~ > 正则匹配 ~/~* > 普通前缀匹配。正则 location 按配置文件中的出现顺序匹配,第一个命中的生效。确保替换串中的变量(如 $1)未被意外截断或为空。











