重定向死循环最常见原因是后端误判协议,解决核心是nginx透传x-forwarded-proto $scheme、host $host和x-forwarded-for $proxy_add_x_forwarded_for,并让后端信任该头。

重定向死循环最常见原因,是后端应用(如 Django、Spring Boot、WordPress)只看到 Nginx 转发来的 HTTP 请求,却不知道用户实际访问的是 HTTPS,于是反复跳转 http ↔ https。解决核心就两步:Nginx 正确透传协议信息,后端主动信任并使用它。
必须加的 proxy_set_header 配置
在包含 proxy_pass 的 location 块内,添加以下三行(顺序不重要,但必须存在):
- proxy_set_header X-Forwarded-Proto $scheme; —— 把用户真实协议(http 或 https)告诉后端,$scheme 是自动变量,别写死成 https
- proxy_set_header Host $host; —— 确保后端生成跳转地址时用的是用户访问的域名(如 example.com),而不是上游地址(如 127.0.0.1:8000)
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; —— 保留原始客户端 IP,便于日志和风控
多级代理或 CDN 场景下的调整
如果前面有 Cloudflare、APISIX 或自建网关,它们可能已设置了 X-Forwarded-Proto。此时 Nginx 不应覆盖,而应优先读取上游值:
FastAPI + Flask 混合部署最佳实践,解决路由定义、API 代理等常见问题,适用于同时运行 FastAPI API 与 Flask 前端的场景。
- 用 proxy_set_header X-Forwarded-Proto $http_x_forwarded_proto; 替代 $scheme
- 更稳妥的做法是用 map 指令兜底:先判断上游有没有传,有就用它,没有就 fallback 到 $scheme
后端必须同步启用信任机制
Nginx 传了头,后端不认等于白配。常见框架配置示例:
- Django:在 settings.py 中设 SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https'),并开启 SECURE_SSL_REDIRECT = True
- Spring Boot:配置 server.forward-headers-strategy=framework,或显式启用 RemoteIpValve
- PHP / WordPress:在入口文件(如 wp-config.php)中检查 $_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https',而非只看 $_SERVER['HTTPS']
额外建议:避免 Location 头拼错
即使头传对了,后端仍可能返回含内部地址的重定向(如 Location: http://127.0.0.1:8000/login)。这时可在 Nginx 中用 proxy_redirect 主动改写:
- proxy_redirect ~^http://[^/]+(/.*)$ $scheme://$host$1; —— 把内网地址替换成用户访问的协议+域名
- 若后端还带错误端口(如 :8080),可追加 proxy_redirect ~:(\d+)(/.*|$) $2; 去掉端口部分










