Nginx rewrite配置不当最易导致“重定向次数过多”错误,主因是跳转闭环、last误用、与return/try_files/HTTPS跳转等指令冲突;应通过curl跟踪Location、日志记录URI变化、临时改302及最小化复现排查。

当 Nginx 的 rewrite 规则配置不当,最容易出现的现象就是浏览器提示“重定向次数过多”(ERR_TOO_MANY_REDIRECTS),本质是客户端被反复 301/302 跳转,形成闭环。排查关键在于确认跳转路径是否闭环、是否受条件干扰、以及是否与其它模块(如 return、try_files 或代理逻辑)冲突。
检查 rewrite 是否触发了自身匹配
这是最常见原因:重写后的 URL 又被同一条或另一条 rewrite 规则再次匹配,导致循环。例如:
rewrite ^/old/(.*)$ /new/$1 permanent;
如果 /new/ 路径下没有真实资源,且又有一条规则把 /new/.* 再重写回 /old/,就构成闭环。
建议做法:
- 用
curl -I模拟请求,观察Location响应头变化,追踪跳转链(最多跟 5–6 次); - 在 rewrite 前加
log_format+access_log,记录原始 URI 和重写后 URI(用$request_uri和$uri对比); - 临时把
permanent改成redirect(302),避免浏览器缓存 301,便于反复测试。
注意 rewrite 的执行阶段和 location 匹配顺序
rewrite 在 server 或 location 块中执行,但它的作用时机会影响后续匹配。尤其要注意:
- 在
server级写的 rewrite,会在进入任何location前执行,重写后的 URI 可能落入另一个 location 块,又被其中的 rewrite 处理; - 带有
last标志的 rewrite 会重新匹配 location,而break则不会——误用last是循环高发点; - 正则 location(
~或~*)优先级高于前缀 location,但 rewrite 不改变 location 的选择逻辑,只改 URI 字符串。
比如:rewrite ^/api/(.*)$ /v1/api/$1 last; 后,Nginx 会用 /v1/api/xxx 重新查找 location,若恰好有 location ~ ^/v1/ 且里面又有 rewrite,就可能套娃。
排查与其他指令的交互冲突
rewrite 很少单独作祟,常与以下指令“联手”制造循环:
-
return 301或return 302:和 rewrite 混用时,容易因条件判断缺失造成重复跳转; -
try_files:如果 rewrite 后落到try_files $uri @fallback,而@fallback又触发 rewrite,就形成隐式循环; - HTTPS 强制跳转逻辑:如
if ($scheme != "https") { return 301 https://... }和 rewrite 共存时,未排除已重写路径,会导致 http→https→重写→http 无限切换; - proxy_pass 配合 rewrite:后端返回 302 Location 时,若 Nginx 未正确改写响应头(
proxy_redirect缺失),也可能被前端反复解析跳转。
快速验证与最小化复现
不要在生产配置里反复试错。推荐步骤:
- 备份当前配置,新建一个极简
server块,只保留疑似问题的 rewrite 和必要日志; - 用
nginx -t确保语法正确,再nginx -s reload; - 使用
curl -v http://your-domain/test查看完整跳转过程,重点关注> GET和< Location:行; - 打开
error_log级别为info,rewrite 相关动作(如 “using configuration”, “rewritten data”)会被记录,直接定位哪条规则在反复触发。
不复杂但容易忽略:多数无限重定向,其实只差一个 break、一行 if (!-f $request_filename) 判断,或一次对 $scheme / $host 的校验。


















