直接查看nginx error_log中“rewrite or internal redirection cycle”错误,结合“internally redirecting to”定位卡住uri,再排查permission denied、no such file或debug日志中的rewrite/redirect跳转链及高危指令(如无保护的rewrite、if与try_files冲突)。

直接看 error_log 里的关键线索,重点抓“rewrite or internal redirection cycle”这行错误,再顺藤摸瓜查跳转链和权限问题。
快速定位循环起点
在 Nginx 错误日志中搜索:
- rewrite or internal redirection cycle —— 这是死循环的明确信号
- 紧跟着的 internally redirecting to "/xxx" —— 显示最终卡住的目标 URI(比如
/index.html或/index.php) - 出错前几行的 client、server、request 字段 —— 能还原原始请求路径和 Host,确认是不是 /、/favicon.ico 或某个 API 路径触发的
判断是否因权限或路径不存在引发假循环
很多“重定向循环”其实是表象,真实原因是目标文件根本打不开。继续往下翻日志,留意有没有:
-
Permission denied(如
stat() "/opt/app/dist/index.html" failed (13: Permission denied))—— 说明 Nginx 用户(通常是www-data或nginx)对目录或文件缺少读或执行权限 -
No such file or directory —— 表示
root配置错误,或者try_files最后一项指向的路径压根不存在(例如把root写成项目根目录,却让try_files去找/public/index.html)
用 debug 日志看清每一步跳转
默认 error log 只报结果,不报过程。要看到完整路径链,需临时启用 debug 日志:
- 在
nginx.conf的http块中加:error_log /var/log/nginx/error.log debug; - 确保 Nginx 编译时带
--with-debug(主流系统包一般已支持) - 重启后复现问题,再执行:
sudo tail -f /var/log/nginx/error.log | grep -E "(rewrite|redirect|phase|finalize)" - 你会看到类似:
*123456 rewrite phase: 3, "/api/user" -> "/index.php"和*123456 http finalize request: 500的逐跳记录,清楚显示哪条rewrite、try_files或if规则在反复触发
结合配置检查高危指令组合
找到循环 URI 后,立刻检查对应 location 中是否用了这些易出问题的指令:
-
try_files $uri $uri/ /index.html;—— 如果/index.html本身又匹配到同一个 location,就会循环。应改用 named location:try_files $uri $uri/ @vuefallback;+location @vuefallback { internal; root /path/to/dist; } -
rewrite ^/(.*)$ /index.php?$1 last;且没加条件限制 —— 容易把所有请求都塞进 PHP,包括静态资源,导致无限兜底 -
if (-f $request_filename) { ... }或if ($args ~ ".*")——if在 location 中行为复杂,常与try_files冲突,优先用try_files替代










