通过反向代理访问 qBittorrent 5.x Web UI 时种子列表不显示——记一次 Cloudflare Rocket Loader 引发的问题
最近把 VPS 上的 qBittorrent 从 4.3.9 升级到了 5.1.2(Docker 安装),随后发现一个奇怪的问题:通过另一台 VPS 上的 Vertex 反向代理访问 Web UI 时,页面能打开,顶部菜单也在,但种子列表完全空白,菜单栏点击也无响应。而直接用 IP 访问,或者通过自动化脚本调用 API,一切正常。
折腾了一段时间,最终发现罪魁祸首是 Cloudflare 的 Rocket Loader 功能。这篇文章记录完整的排查思路,希望对遇到类似问题的人有所帮助。
问题现象
- qBittorrent 版本:5.1.2(Docker)
- 访问方式 A:直接访问 VPS IP + 端口 → 正常
- 访问方式 B:通过 Vertex 代理访问 → 页面加载但种子列表为空,且与组件的交互失效
- 自动化脚本通过 Vertex 调用 API(添加/删除种子等)→ 正常
- 同样通过 Vertex 代理旧版 4.3.9 的 Web UI → 正常
初步排查:qBittorrent 5.x 的新安全机制
文章记录的是较为完整的排查过程,TL;DR,请跳转到“解决方案” 章节。
首先考虑到 qBittorrent 5.x 相比 4.x 引入了更严格的安全策略:
- SameSite Cookie:认证 Cookie 设置了
Lax或Strict,跨域请求不携带 - CSRF 防护强化:API 请求需要正确的
Origin/Referer头 - Host Header 校验:防止 DNS Rebinding 攻击,来自未授权 Host 的请求会被拒绝
这些变化可能解释了为什么 4.3.9 正常而 5.x 出问题。
顺着这个方向,我前往相关的设置页面,关闭了 CSRF 保护,Host Header 验证等几个功能,但是没有什么用。
此外,我还找到了 Web UI 设置里的 Enable reverse proxy support 选项。
Trusted proxies list 的格式
这里补充一个容易踩坑的细节。该字段自 4.5.0
版本起支持 CIDR 子网写法,多个条目用分号
; 分隔:
1 | # 单个 IP |

在此处,我也尝试按要求填入 Vertex 所在 VPS 的 IP 后,保存重启——然而问题依旧。
关键转折:用浏览器开发者工具抓包
既然后端 API 没问题(自动化脚本能正常工作),问题一定出在前端。
打开浏览器开发者工具(F12)→ Network 标签页,重新通过 Vertex 加载 Web UI。
截图中出现了两个关键线索:
- 大量 JS 文件状态为
(canceled),而不是 404 或其他 HTTP 错误码 - 所有被取消请求的 Initiator 都是
rocket-loader.min.js:1
(canceled)
意味着请求在完成之前被浏览器主动中止,而触发者是
rocket-loader.min.js——这是 Cloudflare Rocket
Loader 注入的脚本。
继续往下滚动 Network 记录,发现更关键的现象:

同样的 JS 文件被加载了两次:第一次全部 canceled,随后页面自动触发了一次重载,第二次全部 200 成功。
根本原因:Rocket Loader 破坏了 JS 初始化顺序
我的 Vertex 服务是通过域名访问的,而且此域名挂在 Cloudflare 下!
Cloudflare Rocket Loader 的设计初衷是通过异步加载 JS 来提升普通网页的性能,但它对脚本加载顺序做了重排。
qBittorrent 的 Web UI(基于 MooTools)对 JS
初始化顺序有严格要求:MooTools-Core
必须在其他模块之前加载完毕,client.js
需要等待多个依赖就绪后才能初始化种子列表和事件绑定。
Rocket Loader 介入后,打乱了这个顺序:
1 | 正常顺序: |
这也解释了其他几个现象:
- 自动化脚本正常:脚本直接调用
/api/v2/*REST 接口,完全绕过前端 JS,不受 Rocket Loader 影响 - 4.3.9 正常:旧版 Web UI 的 JS 结构对加载顺序容忍度更高,或者碰巧与 Rocket Loader 的重排结果兼容
- 直接 IP 访问正常:绕过了 Cloudflare,Rocket Loader 根本没有机会注入
解决方案
方案一:全局关闭 Rocket Loader
进入 Cloudflare Dashboard:
域名 → Speed → Optimization(或者 Settings) → Content Optimization → Rocket Loader → 关闭
方案二:通过 Page Rules 仅对特定路径关闭
如果域名还有其他用途,不想全局关闭,可以针对 Vertex/qBittorrent 的路径单独设置:
进入 Rules → Page Rules → 新建规则:
1 | URL 匹配:your-domain.com/your-qb-path/* |

验证
关闭 Rocket Loader 后:
- 清除浏览器缓存
- 重新通过 Vertex 访问 qBittorrent Web UI
- 打开 Network 面板确认:所有 JS 文件一次性全部
200,不再出现
canceled,不再有二次重载 - 种子列表正常显示,菜单交互恢复正常
总结
| 现象 | 原因 |
|---|---|
| 种子列表空白、交互失效 | Rocket Loader 打乱 JS 加载顺序,MooTools 初始化失败 |
| 自动化 API 脚本正常 | 直接调用 REST API,不经过前端 JS |
| 4.3.9 正常,5.x 异常 | 5.x Web UI 对 JS 加载顺序更敏感 |
| 第二次加载恢复正常 | 页面检测到初始化失败后自动重载,第二次 Rocket Loader 缓存命中,顺序恢复正常 |
| Initiator 指向 rocket-loader.min.js | 直接暴露了干预者身份 |
排查这类问题的关键在于:当 API 正常但 UI 异常时,优先检查前端
JS 的加载过程,而不是后端配置。浏览器 Network 面板的 Initiator
列是定位问题的利器,(canceled) 状态配合 Initiator
指向第三方脚本,基本可以直接锁定嫌疑人。
如果你的 qBittorrent Web UI 也套了 Cloudflare,遇到类似问题,不妨先把 Rocket Loader 关了试试。
其它
本文的问题排查、写作过程是在 Claude Sonnet 4.6 协作下完成的。尤其是 Rocket Loader 的问题,由 AI 提出,我只是提供了 Debug Tools 中 Network 页面的截图。虽然这只是个免费版,但这非常可贵。

值得肯定的另一点是,比起另外两家(ChatGPT 免费,以及 Gemini Pro),Claude 在遇到不确定的问题时,会主动进行 Web Search 从而得到更加正确的答案。


这次经历也让我有了一些感想。
现有的 AI 在知识广度,问题排查上已经大幅领先人脑了。如果是我自己排查,受限于知识面,我想不到是 Cloudflare 的问题(是的,一开始我以为 Rocket Loader 是 qb 自带的组件,因此没有多想)。
因此,还是学着去使用 ai 吧,抓住新机会,不断学习,跟上潮流。我有预感,会不会使用 ai,也许会成为类似“智能机”与“老人机”之间的一样的鸿沟。
