避免 rewrite 死循环的关键是防止重写后 URI 再次命中自身规则:HTTPS server 块禁用 return 301 https://;rewrite 路径须加锚点(如 ^/api/)或用 location 精确隔离;优先用 location + return 替代 server 级 rewrite;实测 curl -I 验证跳转链是否震荡。

避免 server_name 相关的 rewrite 规则引发死循环,关键不是“怎么配 server_name”,而是防止 rewrite 逻辑在重写后又重新命中自身——尤其当规则跨协议、跨域名或路径设计不严谨时。真正危险的不是 server_name 本身,而是它所承载的 rewrite 行为缺乏终止约束。
别在 HTTPS server 块里写 return 301 https://
这是最常见、最典型的死循环源头。例如:
- 错误配置:
server { listen 443 ssl; server_name example.com;<br> return 301 https://example.com$request_uri; }
浏览器已用 HTTPS 访问,Nginx 却再次跳转到 HTTPS,形成无限跳转。 - 正确做法:HTTP server 块负责跳转,HTTPS server 块只处理业务,不参与任何重定向逻辑。
server { listen 80; server_name example.com;<br> return 301 https://$host$request_uri; }<br>server { listen 443 ssl; server_name example.com;<br> # 这里不写 return 或 rewrite 到 https:// }
rewrite 路径必须加锚点和唯一入口判断
若 rewrite 规则未限定匹配范围,/new/ 可能再次触发 /old/ 的规则。比如:
Linux 性能分析与调优专家,覆盖 CPU、内存、磁盘 I/O、网络、内核参数、编译优化、容器/K8s。适用场景:系统卡顿/高负载、内存不足/OOM/Swap 高、CPU 异常/iowait 高。
- 危险写法:
if ($request_uri ~ ^/api/) {<br> rewrite ^(.*)$ /v1$1 break;<br>}
/v1/api/ 仍满足~ ^/api/,导致二次重写。 - 安全写法:
加起始锚点^/api/,排除 /v1/api/;或用 location 精确隔离:location ^~ /api/ {<br> rewrite ^/api/(.*)$ /v1/api/$1 break;<br>}
同时确保location /v1/不含同类 if 或 rewrite。
慎用 server 级 rewrite,优先用 return 替代
server 块中的 rewrite 在 location 匹配前执行,容易绕过路径控制逻辑。而 return 是原子操作,无重匹配风险:
- 不推荐:
server { server_name old.example.com;<br> rewrite ^/post/(\d+)$ /article/$1 permanent;<br>} - 更稳写法:
server { server_name old.example.com;<br> location ^~ /post/ {<br> return 301 /article/$1;<br> }<br>}
既明确作用范围,又避免 URI 重写后再次进入 server 级匹配。
验证是否循环:用 curl -I 看 Location 头是否震荡
上线前必须实测,不依赖猜测:
- 执行:
curl -I http://example.com/old/path - 观察响应头:
✔ 正常:只返回一次Location: /new/path,状态码 301
✘ 循环:多次请求后 Location 值在两个地址间来回切换,或连续出现多个 301 - 补充验证:
curl -v http://example.com/old/path 2>&1 | grep "Location\|HTTP/"可快速抓取跳转链

















