Skip to main content

Chrome 下载插件 · v0.2(装了就能用)

一句话:让 Chrome 去下载,让程序当指挥官。 程序只会喊"下这个、下到哪了、停",一个字节都不经它的手——所以你在浏览器里装的那个加速器一定能吃到流量。


一、这次改了什么(一句话)

以前装完插件还要在电脑上再装个"传话筒":复制 32 位插件 ID、往 Windows 注册表里登记、让那个传话筒一直开着,三步少一步就失联。 现在插件自己就是会主动打电话的那个人:它在电脑内部的 18888 号门牌(端口)上敲门。 你要做的只有一件事:把插件装进 Chrome。

技术侧一句:控制通道从系统注册的宿主进程换成本机回环 WebSocket;下载字节仍然 100% 由 chrome.downloads 走浏览器内核发起,这条硬约束一点没动。


二、要准备的东西(都是一次性的)

东西 要什么 怎么查
Chrome ≥ 116(本机实测 154) 地址栏 chrome://version
Python 3.11 以上 python --version
aiohttp 可选,不装也能跑 python -m pip install aiohttp==3.14.2

不确定缺什么?先跑体检(只看本机,不联网、不下载):

python check_env.py

它会一行一行告诉你哪一项缺、下一步该敲什么。 其中有一项专门看你把 Chrome 的下载目录改过没有——改过就必须告诉指挥官, 不然它找不到文件、算不了校验(会报"没有文件",其实文件在)。

aiohttp 不在时,指挥官自动换用零依赖实现(标准库手写 RFC6455)。 两条路共用同一套账本与协议代码,功能一致;--json 体检与 health 里会写清用的哪条(字段 transport)。


三、正式安装:一步

  1. 打开 Chrome,地址栏输入 chrome://extensions 回车
  2. 右上角打开「开发者模式」开关
  3. 点「加载已解压的扩展程序」,选中本目录里的 extension 文件夹

完。 不用复制 ID、不用改注册表、不用双击什么常驻、不用去设置页手动授权。

(要上架 Chrome 商店之后同理:点"添加到 Chrome"就完事。)

然后起指挥官:

python bridge.py

出现一行 {"event": "bridge_ready", ...} 就说明它在听了。窗口最小化即可,不用常驻—— 它什么时候在,插件自己找得到;它不在的时候插件安静等,不刷屏。

装完了?再跑一次 python check_env.py。


四、怎么用

人用法(命令行)

python client.py add https://example.com/big.csv      (提交一个下载)
python client.py progress                              (看所有任务进度和网速)
python client.py watch                                 (实时刷屏跟进度,Ctrl-C 停)
python client.py pause  <任务号>                        (暂停)
python client.py resume <任务号>                        (继续)
python client.py cancel <任务号>                        (取消并删掉半成品)
python client.py batch  --file jobs.json               (批量提交)
python client.py health                                (体检:插件连没连上、用的哪条通道)

文件落在你 Chrome 里设的下载目录下的 chrome-dl/ 子目录(默认 C:\Users\你\Downloads\chrome-dl\; 你在 Chrome 设置里改过下载目录,落点就跟着变)。提交时打印一个 16 位任务号,后面所有操作都用它。

机器人用法(Python 里调用,零第三方依赖)

from client import Client

c = Client()                              # 自动读本机 endpoint.json,不用填端口密码

ids = c.download(["https://example.com/a.csv", "https://example.com/b.csv"])
print(ids)                                # 任务号列表

print(c.get_progress())                   # 全部进度;给任务号就只看那一个
c.pause(ids[0]); c.resume(ids[0])
r = c.wait(ids)                           # 等一批下完
for j in r["jobs"]:
    print(j["state"], j["bytesReceived"], j["speedBps"])

print(c.link_status())                    # 插件连没连上 / 门牌 / 配对与 bridgeId

边下边看(SSE 流,标准库就能读):

c.watch(lambda e: print(e.get("jobId"), e.get("state"),
                        e.get("bytesReceived"), e.get("speedBps")), timeout=120)

五、"多久能连上"——三档实话(别当 bug 报)

档 情形 实测承诺
A 插件这会儿还醒着(正在下载 / 刚被事件唤起 / WS 还开着) 几秒(1/2/4/8/16 秒退避重连,走进程内定时器)
B 你点一下扩展图标 ≤1 秒(popup 打开就立刻重连一次)
C 插件睡着了(好久没用) 约 30 秒起,Chrome 可能给得更久

C 档为什么不能更快:Chrome 官方规定扩展的定时器最快 30 秒醒一次 (delayInMinutes / periodInMinutes / when 三者都不能更早,官方原话"at most once every 30 seconds")。 这是平台限制,我们绕不开,也不假装绕得开。所以对外承诺一律写"最长约半分钟",不写"秒级"。

开发者模式加载的未打包版没有这个限制——开发时看到的秒级不代表商店版表现。


六、它到底"多"在哪(说人话,别误会)

  • ✅ 多个文件一起下:默认同时 4 个,同一个网站最多 2 个,谁先下完谁补位。
  • ❌ 不是把一个文件切成 8 块同时下。Chrome 的规矩是"一个文件一条线",插件插不手。
  • 断点续传:中途断网/断电,恢复后接着下,不重头来。前提是服务器支持;服务器不支持时会重头下, 日志里老实写「重头下」(restarted),不会骗你说"续传成功"。

七、不放心?自己验一遍

python test_downloader.py            (全套回归,真跑,约 5-10 分钟)
node tests/test_extension_logic.js   (扩展决策逻辑,**假 chrome API**)
python check_env.py --json           (预检取证)

测试里最关键的几条:

  • V4-b —— 指挥官一旦想自己连外网,当场被掐死并记日志(运行时出站熔断)。
  • V4-c / W17 —— 指挥官和浏览器之间只传"纸条":每条不超过 8192 字节, 超了直接断链;分片、二进制帧同样拒(防止把一张纸条撕成两半绕过这道闸)。
  • W13 —— 双向对暗号:不知道密钥的程序冒充指挥官,扩展会识破并断开; 反过来冒充扩展的程序,指挥官也会当场识破(EXT_HMAC_MISMATCH)。
  • V5 / V6 —— 断点续传是真的(服务器确实收到 Range 并回 206);禁 Range 时如实标"重头下"。
  • V8′ —— 下载进行中杀掉指挥官,重启后字节对齐、不重下、不留幽灵任务。

⚠️ 哪些是"跑不了真机所以没证"的(不许拿上面的绿勾当这些的凭据): W4 20 秒保活是否真让 SW 活过 5 分钟、W4b 打包版 alarm 实钳制、W5 扩展 console 噪音条数、 WS-T0.5 Chrome 154 的"本地网络"门禁落在哪一档、W8 popup 点一下是否 ≤1 秒连上、 W18/W19 popup 文案是否按预期出现 —— 这些必须有人在真 Chrome 里手动加载扩展跑一次, 结果落 tests/ws_probe_report.md;在那之前它们是 UNVERIFIED,本 README 不替它们认账。


八、遇到问题怎么办

现象 意思 这么办
找不到 ...\endpoint.json 指挥官没在跑 python bridge.py
401 BAD_TOKEN 口令不对 别自己填 token,让它自动读 endpoint.json;实在不行删掉 %LOCALAPPDATA%\chrome-dl-bridge\endpoint.json 重启
任务 FAILED: NO_EXTENSION_CONNECTED Chrome 没开 / 插件没装 / 插件睡了还没醒 开 Chrome;等约 30 秒;点一下扩展图标可立刻加速
插件图标上有红色「!」 需要你看一眼:对暗号失败 / 门牌上站着不认识的程序 点开图标,按它给的按钮处置("重新认一下" 或 "拉黑并断开")
18888 这个门牌被别的软件占了 端口冲突 python bridge.py --port 18889(插件那边点图标里的"换个端口")
进度数字隔一会儿才动 插件在打盹(最长约 30 秒) 正常现象;文件仍在下,别重复提交
说"文件不存在"但其实下完了 你改过 Chrome 下载目录 python bridge.py --download-root "你的目录"

审计文件都在这儿,出问题发这几张给我看就行:

%LOCALAPPDATA%\chrome-dl-bridge\bridge_audit.jsonl      ← 指挥官干了什么
%LOCALAPPDATA%\chrome-dl-bridge\ws_trace.jsonl          ← 每张纸条的内容
%LOCALAPPDATA%\chrome-dl-bridge\pairing_audit.jsonl     ← 对暗号的成败记录(安全事件看这张)
%LOCALAPPDATA%\chrome-dl-bridge\egress_blocked.jsonl    ← 有没有被熔断拦下
%LOCALAPPDATA%\chrome-dl-bridge\jobs.json               ← 任务账本
%LOCALAPPDATA%\chrome-dl-bridge\handshake.key           ← 配对密钥(权限 600,别发给别人)

想彻底卸载:在 Chrome 里删掉扩展,再删 %LOCALAPPDATA%\chrome-dl-bridge 整个目录。没有注册表项要清——这一层已经不存在了(见 NM_REMOVAL_NOTE.md)。


九、安全边界(如实说,不粉饰)

只监听 127.0.0.1,别的电脑连不上。文件字节 100% 由 Chrome 网络栈发起: 指挥官、插件、Agent 三方都不许当文件字节的传输通道(回环 HTTP/SSE 与元数据请求是允许的, 这条边界要说准:管的是"字节不许过通道",不是"程序完全不许联网")。

每条控制纸条 ≤8192 字节,服务端显式配置(不是吃库的默认值——aiohttp 的默认是 4 MiB, 吃默认就等于把这条判据写废);超限一律断链 1009,不分片、不收二进制帧。

这一版唯一的实质性安全退让(原来靠 Windows 注册表帮我们认人,现在没了):

改成"第一次连上就算认识(对暗号),以后每次都对暗号"。所以:

  • 万一有个坏程序抢在真指挥官之前占住 18888 门牌,它会被当成"第一个认识的"——这个防不住, 这是"零安装步骤"换来的固有代价(任何没有系统级来源绑定的架构都躲不过)。
  • 同用户的恶意程序也可以读走密钥文件(chmod 600 只防别的登录用户,不防你自己账号下的程序)。
  • 坏程序能做到的上限:让浏览器往你 Chrome 当前默认下载目录下的 chrome-dl/ 里写文件, 文件名可以指定,同名文件会被覆盖(conflictAction: overwrite)。 它读不了你的其他文件、执行不了代码、传不出数据(指令白名单 + 出站熔断 + 纸条审计三重)。
  • 我们能做的:门口换人了就告诉你(图标红「!」+ 文案),你可以一键"断开并忘记此程序"重新配对; 指挥官的"身份证号"(bridgeId)被插件钉扎,变了就告警;所有对暗号的成败单独记一张账。

要不要接受这个代价,由你拍板。 不接受的话,可退回"首次一次配对(你在 popup 点一次允许)", 代价是不再"零步骤"。


十、给"老奶奶"的三句话

  1. 以前装完插件还要在电脑上再装个传话筒(复制 ID、改注册表、让它常驻); 现在装完插件就完事,什么都不用再做。
  2. 插件会自己在电脑内部的 18888 号小门上敲门找你的机器人。插件醒着 → 几秒钟接上; 插件睡了 → 至少半分钟(Chrome 官方定的,绕不开),之后就一直连着。想快,点一下插件图标。
  3. 下东西从头到尾都是浏览器在干,插件和机器人之间只传"网址、编号、下了多少"这种小纸条—— 所以你的加速器一定吃得到流量;这条规矩一点没变。

十一、v0.3:装了包之后的用法(三步,命令都是真跑过的)

先装包(这一步不标 runnable —— 它是环境改动,跑一次就动一次 base, 计划 §8.6 第 1 条把"不该真跑的行"明确排除在外):

python -m pip install --no-build-isolation .

下面三块标了 # runnable,会被 workflow/run_readme_examples.py 抽取真跑。 占位符 <URL> / <jobId> / <STATE_DIR> / <PORT> / <KNOWN_HEX> 由抽取器填 (<KNOWN_HEX> 用 mock_server.expected_sha256() 现算,不手写)。

1) 看路径、看门牌、看扩展在哪

# runnable
# exit: 0
chrome-dl env --json
# runnable
# exit: 0
chrome-dl extension-path --json

2) 下一次真下载,并验完整性(三条真下载级命令,T7-a3)

# runnable
# exit: 0
chrome-dl download "<URL>" --filename readme-demo.bin --sha256 <KNOWN_HEX> --wait --timeout 180 --state-dir <STATE_DIR> --port <PORT>
# runnable
# exit: 0
chrome-dl list --state-dir <STATE_DIR> --port <PORT>
# runnable
# exit: 0
chrome-dl wait <jobId> --timeout 120 --state-dir <STATE_DIR> --port <PORT>
# runnable
# exit: 0
chrome-dl show <jobId> --state-dir <STATE_DIR> --port <PORT>

第四条把完整性说清楚:show 打出来的账本里 sha256Actual 必须是 OK。 为什么第一步要带 --sha256:Bridge 的校验分支是"没给期望哈希就返回 SKIP", 不带 --sha256 的下载只证明"没崩",证明不了"文件是那个文件"。

3) 后台桥与自动拉起

# runnable
# exit: 0
chrome-dl daemon status --state-dir <STATE_DIR>
# runnable
# exit: 2
chrome-dl bogus-verb --state-dir <STATE_DIR>

第二条是故意敲错的:exit: 2 明写预期非 0,抽取器会去核对它真的非 0、 真的给人话、真的没甩 traceback。报错面也要被跑过,不然没人知道它长什么样。

关掉自动拉起 / 不想常驻

# runnable
# exit: 0
chrome-dl --no-auto-spawn env --state-dir <STATE_DIR>

环境变量 CHROME_DL_NO_AUTOSPAWN=1 也能关;chrome-dl daemon stop 只结束 本项目自己归因得到的桥,归因不过的进程一律不动。

MCP 客户端配置

Claude Code / Antigravity / 任何 stdio MCP 客户端的接法见 docs/mcp-setup.md。

Metadata

Release files for chrome-downloader-client 0.3.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for chrome-downloader-client 0.3.0
File Size Uploaded
chrome_downloader_client-0.3.0.tar.gz 210.5 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for chrome-downloader-client 0.3.0
File Interpreter ABI Platform
chrome_downloader_client-0.3.0-py3-none-any.whl Python 3 none any Details

Total release size: 348.1 kB

Release files / chrome_downloader_client-0.3.0.tar.gz

Download URL chrome_downloader_client-0.3.0.tar.gz
Size 210.5 kB
Tags Source
SHA-256 checksum
How to use checksums
4a040cd4b9d1d3eeadb105d615e40b097e87f3438acdabed9d011f21d2970bb1
BLAKE2b-256 checksum
How to use checksums
cf66b80faa26286e7f37776feca3bfd83921d4d42954b6e6ee9a46d1c4b6eec3
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.11.15

Release files / chrome_downloader_client-0.3.0-py3-none-any.whl

Download URL chrome_downloader_client-0.3.0-py3-none-any.whl
Size 137.6 kB
Tags Python 3
SHA-256 checksum
How to use checksums
15b7f4dccc19255fa39b84fca8ceea920258e65dfe0012c36be0a35fd4b9c739
BLAKE2b-256 checksum
How to use checksums
d55d6ebe90fdc36c393c648ea0a8075422c373f98cc8e52605d7155d71ffa7ef
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.11.15

Release history Release notifications | RSS feed

This release

0.3.0 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page