
打开网站时,浏览器提示“重定向次数过多”“网页重定向次数过多”或 ERR_TOO_MANY_REDIRECTS,通常表示浏览器在多个URL之间反复跳转,达到重定向次数上限后停止访问。
常见循环包括HTTP与HTTPS互相跳转、带 www 与不带 www 互相跳转、CDN与源站协议判断冲突,以及网站程序识别不到真实访问协议,持续把用户重定向到自己认为正确的地址。
清理Cookie有时能解决登录状态造成的循环,但无法修复服务器、CDN和应用配置冲突。正确的排查方法是先记录完整重定向链,找出哪两个或多个URL构成闭环,再逐层检查浏览器、CDN、负载均衡器、Nginx和网站程序。
本文介绍一套适用于常见网站环境的重定向循环排查流程,并提供Nginx、HTTPS、反向代理和CDN场景的处理方法。
一、什么是重定向次数过多
HTTP重定向通常通过以下状态码和 Location 响应头实现:
- 301:永久重定向。
- 302:临时重定向。
- 303:要求客户端使用GET访问另一个地址。
- 307:临时重定向,并保留请求方法。
- 308:永久重定向,并保留请求方法。
正常重定向可能是:
http://example.com
-> https://example.com
循环重定向可能是:
http://example.com
-> https://example.com
-> http://example.com
-> https://example.com
也可能发生在主机名之间:
https://example.com
-> https://www.example.com
-> https://example.com
浏览器为了避免无限请求,会在达到自身限制后显示重定向过多。
需要注意,Nginx内部 rewrite 或 try_files 也可能形成内部URI循环。这类问题通常不是浏览器收到大量3xx,而是Nginx返回500,并在错误日志中记录内部重定向循环。两者排查方式不同。
二、先用curl查看完整重定向链
不要只在浏览器中反复刷新。先执行:
curl -I http://example.com
查看HTTPS:
curl -I https://example.com
重点关注:
- HTTP状态码。
Location指向的地址。Server、CDN或代理相关响应头。- 是否设置了新的Cookie。
自动跟随重定向并显示每一步响应头:
curl -IL --max-redirs 10 https://example.com
显示更详细的连接信息:
curl -ILv --max-redirs 10 https://example.com
如果最终出现类似“超过最大重定向次数”的错误,应把每一步的状态码和 Location 按顺序记录下来。
排查时分别测试四种常见入口:
curl -I http://example.com
curl -I https://example.com
curl -I http://www.example.com
curl -I https://www.example.com
这样可以快速判断循环来自协议还是主机名规范化。
三、绕过CDN直接测试源站
网站使用CDN、WAF或云负载均衡时,公网访问结果并不完全代表源站自身行为。
在确认源站IP和证书匹配的前提下,可使用 --resolve 将域名临时指向指定IP:
curl -I --resolve example.com:443:203.0.113.10 https://example.com
测试源站HTTP:
curl -I --resolve example.com:80:203.0.113.10 http://example.com
将示例IP替换为实际源站IP。
结果判断:
- 经过CDN循环,直连源站正常:重点检查CDN HTTPS模式、重定向规则和缓存。
- 直连源站也循环:重点检查Nginx和网站程序。
- 只有某个节点或地区循环:检查CDN节点配置、缓存和分区域规则。
- 直连源站返回错误证书或错误站点:先确认SNI、虚拟主机和源站监听配置。
不要为了测试直接关闭安全组或暴露源站端口。优先使用已有访问控制,并在测试完成后恢复临时放行规则。
四、最常见原因:HTTP与HTTPS互相跳转
典型情况是外层CDN使用HTTPS接收用户请求,却使用HTTP访问源站;源站看到的是HTTP,于是把请求重定向到HTTPS。CDN再次以HTTP回源,循环重新开始。
请求链可能是:
浏览器通过HTTPS访问CDN
-> CDN通过HTTP访问源站
-> 源站强制跳转HTTPS
-> 浏览器再次访问CDN HTTPS
-> CDN仍通过HTTP回源
解决方向不是简单删除所有HTTPS跳转,而是统一协议策略:
- 条件允许时,让CDN使用HTTPS连接源站。
- 为源站配置有效证书。
- 确认CDN的边缘HTTPS和回源HTTPS设置一致。
- 避免CDN和源站同时存在互相冲突的强制跳转规则。
如果CDN提供“灵活”“仅边缘加密”之类模式,需要特别检查它是否使用HTTP回源。源站同时强制HTTPS时,往往会产生循环。
五、反向代理没有传递真实协议
网站经过CDN、负载均衡器或另一层Nginx后,后端应用看到的连接可能是HTTP,即使用户实际访问的是HTTPS。
代理层通常需要传递真实协议信息:
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;
但这里有一个容易忽略的问题:如果Nginx前面还有可信代理,当前 $scheme 可能只是代理到Nginx这一段的协议,不一定是用户原始协议。
在可信代理明确传递 X-Forwarded-Proto 的环境中,应结合架构决定是沿用上游值还是重新设置。不要无条件信任来自公网客户端的该请求头,否则可能造成协议判断错误或安全问题。
应用层也必须正确识别代理头。仅在Nginx设置头部,但应用框架没有配置可信代理,仍可能持续误判HTTPS状态。
六、检查Nginx的HTTP跳转配置
常见的HTTP跳转到HTTPS配置:
server {
listen 80;
server_name example.com www.example.com;
return 301 https://example.com$request_uri;
}
HTTPS主站:
server {
listen 443 ssl;
server_name example.com;
ssl_certificate /path/to/fullchain.pem;
ssl_certificate_key /path/to/privkey.pem;
root /var/www/example;
}
www跳转到主域名可以单独配置:
server {
listen 443 ssl;
server_name www.example.com;
ssl_certificate /path/to/fullchain.pem;
ssl_certificate_key /path/to/privkey.pem;
return 301 https://example.com$request_uri;
}
这种写法将协议规范化和主机名规范化集中在清晰的server块中,通常比在多个location里重复rewrite更容易排查。
修改配置后执行:
sudo nginx -t
确认无误后平滑重载:
sudo systemctl reload nginx
七、检查www与非www互相跳转
常见冲突包括:
- CDN规则把
example.com跳转到www.example.com。 - Nginx又把
www.example.com跳回example.com。 - 网站程序的站点地址与Nginx规范域名不一致。
- 多个插件或中间件分别执行不同方向的跳转。
先确定唯一标准域名,例如:
https://example.com
然后确保以下位置全部一致:
- DNS和CDN主机规则。
- CDN重定向规则。
- Nginx
server_name和return。 - 网站后台的站点URL。
- 应用配置文件和环境变量。
- SEO canonical和站点地图。
不要让不同层分别“猜测”标准域名。应明确只有一套规范化方向。
八、Nginx rewrite规则形成循环
例如下面的规则可能与其他配置产生冲突:
rewrite ^/(.*)$ https://example.com/$1 permanent;
如果它位于已经处理HTTPS请求的server或location中,每次请求都可能再次触发重写。
对于固定跳转,优先使用更直接的 return:
return 301 https://example.com$request_uri;
检查完整生效配置:
sudo nginx -T
由于输出可能包含证书路径、内部域名和其他敏感配置,分享给他人前应先脱敏。
搜索跳转相关指令:
sudo nginx -T 2>&1 | grep -n -E 'server_name|return 30[1278]|rewrite|try_files|error_page'
重点检查:
- 主配置文件和
include文件中是否重复设置。 - 同一域名是否存在多个server块。
rewrite是否在目标URL上再次匹配。error_page是否返回原location。try_files的最后参数是否造成内部循环。
九、内部重定向循环为什么常返回500
如果Nginx在内部不断把请求改写到另一个URI,又重新进入相同location,通常会在错误日志中看到:
rewrite or internal redirection cycle
查看日志:
sudo tail -n 100 /var/log/nginx/error.log
常见错误示例:
location / {
try_files $uri /index.html;
}
当 /index.html 不存在,并且请求再次进入同一location时,可能形成内部循环。实际是否循环取决于完整配置。
对于前端单页应用,应确保回退文件真实存在:
location / {
try_files $uri $uri/ /index.html;
}
同时确认:
ls -l /var/www/example/index.html
不能只复制配置示例,而不检查root路径和文件是否存在。
十、网站程序识别HTTPS错误
WordPress、Laravel、Django、Node.js和其他框架通常会根据请求协议、主机名或代理头生成绝对URL。
如果应用认为当前请求是HTTP,它可能强制跳转到HTTPS;但外层代理已经使用HTTPS,浏览器重新请求后,应用仍看到HTTP,于是继续跳转。
排查方向:
- 确认应用是否配置可信代理。
- 确认应用读取哪个协议头。
- 检查站点URL和基础URL配置。
- 检查环境变量中的协议与域名。
- 暂时停用重定向、安全或缓存插件进行对比。
- 对照应用日志和请求ID确认跳转由哪一层产生。
不要在不了解代理边界时直接让应用信任所有转发头。应只信任实际使用的反向代理或内部网络。
十一、Cookie和登录状态造成循环
有些循环只发生在后台登录、用户中心或单点登录页面,常见原因包括:
- 登录Cookie的Domain不正确。
- Cookie被设置为Secure,但用户从HTTP入口访问。
- SameSite策略与跨站登录流程冲突。
- Session无法写入或每次请求都丢失。
- 登录成功后跳回登录页。
- 多个站点共享Cookie名称但配置不同。
可以使用浏览器无痕窗口测试,或只删除当前域名的Cookie。不要一开始就清空整个浏览器数据。
如果无痕窗口正常,而普通窗口循环,应检查Cookie和缓存;如果所有客户端都循环,则更可能是服务器或代理配置问题。
十二、HSTS和浏览器缓存的影响
浏览器可能缓存301重定向,也可能通过HSTS自动把HTTP升级为HTTPS。因此,修改服务器配置后,浏览器地址栏显示的行为不一定完全代表当前服务器响应。
建议同时使用:
curl -I http://example.com
curl -I https://example.com
并使用无痕窗口或新的测试域名进行验证。
测试重定向规则时,可以先使用302,确认路径正确后再改为301。永久重定向可能被浏览器、CDN和搜索引擎缓存,修改后的验证成本更高。
不要为了排查循环轻易移除已部署的HSTS,尤其是已经启用 includeSubDomains 或提交预加载的域名。应先修复HTTPS链路和重定向逻辑。
十三、CDN缓存和边缘重定向规则
即使源站配置已经修复,CDN仍可能缓存旧的301或执行边缘跳转。
检查:
- 边缘重定向规则。
- HTTP转HTTPS开关。
- www规范化规则。
- 页面规则或URL转换规则。
- CDN缓存的301/302响应。
- 回源Host和回源协议。
- 多个CDN或代理是否串联。
修改后应按URL精确清理相关缓存,并再次比较“经过CDN”和“直连源站”的结果。不要在没有确认原因时全站清缓存,因为这可能造成源站流量瞬间增加。
十四、常见循环组合与解决方向
| 循环现象 | 常见原因 | 处理方向 |
|---|---|---|
| HTTP与HTTPS互跳 | CDN使用HTTP回源,源站强制HTTPS | 改为HTTPS回源并统一协议策略 |
| www与非www互跳 | CDN、Nginx和应用规范域名不一致 | 只保留一个跳转方向 |
| 登录页与后台互跳 | Cookie、Session或认证回调错误 | 检查Cookie域、Secure、Session和回调地址 |
| HTTPS反复跳到自身 | 应用未识别代理后的真实协议 | 配置可信代理和协议头 |
| Nginx返回500 | rewrite、try_files或error_page内部循环 | 检查错误日志和完整生效配置 |
| 只有浏览器异常 | 301、HSTS或Cookie缓存 | 使用curl和无痕窗口对比 |
| 只有CDN访问异常 | 边缘规则、回源协议或缓存 | 直连源站对比并检查CDN配置 |
十五、推荐的完整排查顺序
- 记录报错域名、完整URL、发生时间和影响范围。
- 使用
curl -I分别测试HTTP、HTTPS、www和非www入口。 - 使用
curl -IL --max-redirs 10记录完整跳转链。 - 找出重复出现的两个或多个URL,判断是协议、域名还是路径循环。
- 使用
--resolve在安全条件下绕过CDN测试源站。 - 检查CDN回源协议、HTTPS模式、边缘跳转和缓存。
- 使用
nginx -T检查server、return、rewrite、try_files和error_page。 - 检查代理传递的Host、
X-Forwarded-Proto和应用可信代理设置。 - 核对网站程序的站点URL、环境变量、插件和登录Cookie。
- 修复后先用302测试,再决定是否使用301或308。
- 分别验证浏览器、curl、CDN和源站结果。
- 确认搜索引擎、站点地图和canonical统一到最终URL。
总结
网站提示重定向次数过多,本质上是协议、域名、路径或登录状态在多个规则之间形成闭环。最常见的问题不是某一条跳转本身错误,而是CDN、Nginx和网站程序各自执行了不同方向的规范化。
排查时应先用 curl 还原每一步状态码和 Location,再通过直连源站判断问题发生在CDN还是源站。对于反向代理环境,还要确认真实协议和主机名能够安全、准确地传递给应用。
最终配置应只有一个明确的标准URL,并让CDN、Nginx、应用和SEO设置保持一致。与其不断增加例外规则,不如减少重复跳转层级,让每一层的职责清晰可验证。




