配置Certbot启用HTTPS后Nginx出现Too many redirects重定向过多问题求助
看起来你遇到的是HTTPS启用后典型的重定向循环问题,我来帮你一步步排查解决:
首先先排除最容易忽略的小问题——清空浏览器缓存,或者用隐私窗口访问试试,有时候旧的重定向缓存会导致莫名其妙的循环。
接下来咱们从Nginx配置和后端API两个核心方向找问题:
一、Nginx配置里的潜在问题
去掉/api位置多余的root指令
看你HTTPS server块里的/api配置,加了root /home/ubuntu/myBills/backend;,但反向代理场景下这个配置完全没用(proxy_pass已经直接指向你的Node服务了),甚至可能干扰Nginx的路径匹配逻辑。建议删掉这行,修改后的/api location如下:location /api { proxy_set_header X-Forwarded-Proto $scheme; # 保留这行传递协议信息 proxy_pass http://localhost:3000; proxy_connect_timeout 60s; proxy_read_timeout 5400s; proxy_send_timeout 5400s; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection 'upgrade'; proxy_set_header Host $host; proxy_cache_bypass $http_upgrade; }检查Certbot自动添加的SSL配置
Certbot生成的options-ssl-nginx.conf文件里,有些版本会自动加入强制HTTPS的重定向规则,如果你的HTTPS server块里包含了这个文件,同时80端口的server块又在做HTTP→HTTPS的重定向,就可能形成循环。
打开/etc/letsencrypt/options-ssl-nginx.conf看看有没有类似return 301 https://$server_name$request_uri;的代码,如果有,直接注释掉就行——80端口的重定向已经足够了。确认请求是否匹配到了正确的server块
你提到自己站点的my-bills-access.log是空的,但主nginx的access.log有记录,这说明请求根本没走到你的HTTPS server块!建议检查:- 有没有其他server块设置了
listen 443 ssl default_server;?默认server会优先匹配所有未明确匹配的请求。 - 确认访问的域名和server_name完全一致(比如有没有拼写错误,或者带了多余的后缀)。
- 有没有其他server块设置了
二、Node.js API的协议判断问题
这个是最容易踩坑的点!因为Nginx是把HTTPS请求通过http协议转发到localhost:3000的,所以你的Node API拿到的req.protocol是http,如果API里有强制跳转到HTTPS的逻辑,又没有读取你设置的X-Forwarded-Proto头,就会无限循环:
- 浏览器发HTTPS请求→Nginx转发给API(http)→API认为是http请求,重定向到HTTPS→Nginx再转发给API→循环...
如果是Express框架,你需要添加中间件来读取X-Forwarded-Proto头判断协议:
app.use((req, res, next) => { // 只在生产环境(Nginx反向代理下)处理,避免本地开发受影响 if (process.env.NODE_ENV === 'production') { const proto = req.get('X-Forwarded-Proto'); if (proto === 'http') { return res.redirect(`https://${req.headers.host}${req.url}`); } } next(); });
如果你的API用了其他框架,也要确保它能正确识别X-Forwarded-Proto头,而不是直接用本地请求的协议。
最后,测试并重启Nginx
修改配置后,先验证配置是否合法:
sudo nginx -t
如果没问题,重启Nginx生效:
sudo systemctl restart nginx
这样处理后,应该就能解决重定向循环的问题了,如果还有问题,可以把浏览器开发者工具里的网络请求链条(重定向的每一步)贴出来,或者补充主nginx日志里的请求详情,我再帮你排查。
备注:内容来源于stack exchange,提问作者Valor_

