直接答案:先用不自动跟随跳转的请求记录每一跳状态码和 Location,找出 URL 在哪两个状态之间来回。Cloudflare 常见根因是边缘使用 Flexible,而源站又强制 HTTP 跳 HTTPS:边缘回源 HTTP,源站再跳 HTTPS,浏览器于是不断循环。优先让源站部署有效证书并把 Cloudflare 调整到 Full (Strict),再统一只保留一层 HTTP→HTTPS 和主机名规范化规则;不要同时在 CDN、Nginx、面板和应用各写一套。
本文处理启用 Cloudflare、修改 SSL/TLS 模式、WordPress/Nginx 跳转或域名规范化后出现的循环。若页面直接返回 525/526、连接超时或源站无响应,应先解决 TLS 或网络,而不是继续增加 301。
本文按 2026 年 9 月可查的官方文档核对。示例命令以只读取证为主;凡涉及删除、覆盖、重启、权限、网络或数据库参数的动作,都应先确认操作对象、备份、维护窗口和带外恢复入口。不同发行版与软件版本的路径可能不同,必须先查询实际配置再改。
先用证据判断故障在哪一层
| 现象或检查点 | 它能说明什么 | 直接证据 | 不要误判为 |
|---|---|---|---|
| http 与 https 互相跳 | 边缘回源协议和源站强制规则冲突 | 逐跳 Location 与 Cloudflare 模式 | 浏览器 Cookie 问题 |
| www 与根域互相跳 | 两层规范域规则方向相反 | 每跳 Host 与 Location | DNS CNAME 循环 |
| 仅登录或后台循环 | 应用代理信任、会话或回调 URL 错 | 应用日志、Set-Cookie 与 X-Forwarded-Proto | 全站 TLS 故障 |
| 绕过 Cloudflare 正常 | 问题位于边缘规则或边缘到源站链路 | 灰云/直源受控对照 | 源站完全健康 |
| 无 Location 却浏览器循环 | JavaScript、meta refresh 或服务工作线程 | 响应正文与浏览器网络瀑布 | HTTP 301循环 |
这张表的用法不是“看到一个关键词就改一个参数”,而是把客户端、DNS或边缘、Web 代理、应用、数据层依次分开。至少保留故障时间、完整 URL、状态码、关键响应头、同一时刻的服务日志和一份正常样本。只有时间能够对齐,才能判断两个现象是否属于同一次故障。
六步排查与修复顺序
1. 保存完整跳转链
使用 curl -I 看单跳,再用有限次数的 -L 记录链路;不要设置无限跟随。写下每跳协议、主机、路径、状态码、Location、Server 和 CF-Ray,确认是协议循环、主机名循环还是应用路径循环。
2. 核对 Cloudflare 加密模式
确认当前是 Off、Flexible、Full 还是 Full (Strict),并核对源站 443 是否有覆盖业务域名的有效证书。若条件允许,以 Full (Strict) 建立端到端验证;不要为了消除错误长期退回不校验证书的模式。
3. 隔离边缘跳转规则
检查 Redirect Rules、Page Rules、Bulk Redirects、Always Use HTTPS 和 Workers。临时停用时一次只改一条并记录规则 ID;如果循环消失,不代表源站规则一定正确,还要恢复到明确的单一责任层。
4. 检查源站和应用协议认知
查看 Nginx/Apache 301 规则、面板强制 HTTPS、WordPress 站点 URL 与反向代理可信配置。应用应从受信代理的 X-Forwarded-Proto 判断外部协议,不能盲信任何客户端自带头。
5. 合并规范化顺序
把 HTTP→HTTPS、非首选主机→首选主机、旧路径→新路径设计成尽量一次跳转,避免 A 规则跳到 B、另一层又把 B 改回 A。查询参数和非 GET 请求的语义也要测试。
6. 清缓存后做多路径验收
规则修正后清理相关边缘缓存和浏览器站点数据只作为验收步骤,不当作根因修复。测试根域、www、HTTP、HTTPS、登录、回调和深层 URL,并从源站日志确认最终请求协议与 Host。
可复制的只读取证命令
以下命令中的域名、服务名、路径和时间范围要替换为自己的真实值。先执行查询命令并保存原始输出;不要把“命令能运行”误当成“业务已恢复”。
text
curl -sS -o /dev/null -D - http://www.your-domain.tld/path
curl -sS -o /dev/null -D - https://www.your-domain.tld/path
curl -sS -L --max-redirs 8 -o /dev/null -w '%{url_effective} %{http_code}\n' https://www.your-domain.tld/path
curl -kI --resolve www.your-domain.tld:443:203.0.113.10 https://www.your-domain.tld/path
nginx -T
curl -sS -o /dev/null -D - http://www.your-domain.tld/path:查看第一跳状态和 Location,不自动跟随curl -sS -o /dev/null -D - https://www.your-domain.tld/path:对比 HTTPS 第一跳及边缘响应头curl -sS -L --max-redirs 8 -o /dev/null -w '%{url_effective} %{http_code}\n' https://www.your-domain.tld/path:有限跟随并在达到上限前终止循环curl -kI --resolve www.your-domain.tld:443:203.0.113.10 https://www.your-domain.tld/path:受控直连源站测试 Host 与 SNI;不要把 -k 当生产验证nginx -T:读取实际生效配置,查找 return、rewrite 和代理头;输出可能含路径信息需脱敏
如命令输出包含公网 IP、用户名、Cookie、令牌、数据库连接串或客户数据,分享工单前先脱敏。对比时保留时间戳、时区和命令本身,否则后来无法复现同一观察条件。
五个最容易扩大故障的误区
- 反复清 Cookie:可能让某个会话暂时恢复,却不能修复 HTTP 层互相跳转。
- 把 Flexible 与源站强制 HTTPS 叠加:这是最常见的协议闭环之一。
- 同时修改四层规则:循环消失后无法知道是哪条规则,后续发布容易复发。
- 长期使用 curl -k 验收:它忽略证书校验,可能把错误证书当正常。
- 只测首页:登录、后台、Webhook 和带查询参数的路径可能走不同规则。
变更、回滚与数据边界
修改前导出 Cloudflare 规则、记录 SSL 模式、保存 Nginx 与应用配置。任何变更导致登录、支付回调或 API 方法被错误重写时,立即恢复上一条明确可用的规则,而不是再叠加例外。切换 Full (Strict) 前必须先验证源站证书和 443;若源站证书部署失败,可恢复原模式作为短时缓解,但要保留修复计划,不能把降级当最终状态。
如果只能先恢复服务、还不能确认根因,应把措施标记为“临时缓解”,例如限流、摘除单节点、切回上一配置或临时绕过一层代理。恢复后仍要在受控环境复现原因,并验证同类故障不会在下一次重启、发布或高峰重新出现。
统一验收清单
- [ ] 完整跳转链已保存且无闭环
- [ ] Cloudflare 加密模式与源站证书匹配
- [ ] HTTP 到 HTTPS 不超过必要跳数
- [ ] 根域与 www 只有单一首选方向
- [ ] 应用正确识别外部协议
- [ ] 登录、后台和回调不循环
- [ ] TLS 校验未使用跳过选项
- [ ] 边缘与源站日志能对应最终请求
验收必须同时覆盖机器内部和真实外部路径。首页返回 200 不能证明上传、长连接、登录、数据库写入或移动端都正常;同样,控制台显示“运行中”也不能证明应用已能处理请求。至少选一个正常请求、一个边界请求和一个失败请求,记录预期与实际结果。
相关内容与隔离测试入口
建议先阅读Cloudflare 521到524排查、SSL证书续期失败、Nginx反向代理配置,把本问题放回完整请求链路。若生产环境不适合直接试验,可查看美国轻量云的当前规格与库存,搭建与生产隔离的复现环境;测试机不能替代生产备份,价格、库存和可选配置以实时产品页为准。
常见问题
为什么关闭 Cloudflare 就正常?
说明故障与边缘规则、加密模式或边缘到源站协议有关,是定位线索;关闭代理会失去防护和缓存,不应直接当长期方案。
把 SSL 模式改成 Flexible 能快速解决吗?
有时反而制造循环,而且边缘到源站未加密。应在源站部署证书并使用 Full (Strict) 作为目标。
301 和 302 哪个更容易循环?
两者都能循环,关键是 Location 规则互相指向。排障期不要让浏览器永久缓存干扰判断,可先用命令行看原始响应。
WordPress 后台循环一定是插件吗?
不一定。站点 URL、代理协议头、Cookie 安全属性和缓存均可能参与,应从跳转链和应用日志判断。
修复跳转后需要提交搜索引擎吗?
先保证规范 URL 返回稳定 200、canonical 正确、旧 URL 单向跳转。是否提交属于后续动作,不应把提交成功写成已恢复排名。