Nginx移除URL末尾斜杠时出现Too_many_redirect循环问题求助
解决方案
问题根源
- 第一个
example.com:443server块中冗余的location /配置会被最后的return 301完全覆盖,无实际作用。 - 原
rewrite ^(/.*?)/+$ $1 permanent;规则未排除根路径/,会导致/被重定向到/,触发无限循环。 - rewrite规则放在server块而非location块中,执行顺序不符合预期,易和proxy_pass逻辑冲突。
修改后的完整配置
# 处理example.com的HTTPS请求,直接重定向到www域名 server { server_name example.com; listen 443 ssl; # managed by Certbot ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem; # managed by Certbot ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem; # managed by Certbot include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot return 301 https://www.example.com$request_uri; } # 处理www.example.com的HTTPS请求,移除末尾斜杠后代理到后端 server { server_name www.example.com; listen 443 ssl; # managed by Certbot ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem; # managed by Certbot ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem; # managed by Certbot include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot merge_slashes off; location / { # 仅对非根路径的末尾斜杠进行重定向,避免根路径循环 rewrite ^(.+)/+$ $1 permanent; # 代理到后端服务 proxy_pass http://127.0.0.1:9003; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; } } # 处理HTTP请求,重定向到HTTPS的www域名 server { server_name example.com www.example.com; listen 80; return 301 https://www.example.com$request_uri; }
关键调整说明
- 清理冗余配置:删除第一个server块中无用的
location /,让重定向逻辑更清晰。 - 精准的rewrite规则:使用
^(.+)/+$替代原正则,确保只匹配非空且末尾带斜杠的路径(比如/test/→/test),根路径/不会被匹配,避免循环。 - 调整规则位置:将rewrite规则放到
location /内部且在proxy_pass之前执行,保证先完成路径重定向,再代理到后端服务。 - 明确HTTP监听:给最后处理HTTP的server块加上
listen 80,消除配置歧义。
额外注意事项
如果后端服务(127.0.0.1:9003)本身会对无斜杠的路径返回带斜杠的重定向,需要同步调整后端配置,让其和Nginx的规则保持一致,否则仍会出现循环。
内容的提问来源于stack exchange,提问作者Vivek Sharma
相关产品推荐
相关产品推荐

