# cloakfetch-gateway CloakFetch Gateway 是局域网内使用的浏览器网络执行服务。其他局域网机器可以通过 HTTP API 调用真实 CloakBrowser Chromium 发起请求,并通过 Web Console 观察代理、Cookie、缓存、重定向、页面加载和 Chromium 内部网络事件。 它不是 HTTP/SOCKS 代理,也不是通用爬虫框架。当前只保留 GET document navigation,不提供 raw HTTP 引擎,不支持 image/fetch 专用模式。 ## 运行 ```powershell npm install npx cloakbrowser install $env:CLOAKFETCH_HOST = "0.0.0.0" $env:CLOAKFETCH_HEADLESS = "false" $env:CLOAKFETCH_CONCURRENCY = "4" $env:CLOAKFETCH_PROXY = "http://127.0.0.1:7890" npm run dev ``` 生产构建和运行: ```powershell npm run build npm run start ``` 局域网访问控制台: ```text http://<服务器局域网IP>:9230/console ``` 服务不会自动获取或猜测服务器局域网 IP。 ## 配置 ```text CLOAKFETCH_HOST=0.0.0.0 CLOAKFETCH_PORT=9230 CLOAKFETCH_PROFILE=profile CLOAKFETCH_PROXY=http://127.0.0.1:7890 CLOAKFETCH_HEADLESS=false CLOAKFETCH_CONCURRENCY=4 CLOAKFETCH_TIMEOUT_MS=30000 CLOAKFETCH_MAX_BODY_MB=64 CLOAKFETCH_HISTORY_LIMIT=1000 CLOAKFETCH_WS_HEARTBEAT_MS=15000 CLOAKFETCH_NETWORK_HISTORY_LIMIT=10000 CLOAKFETCH_NETWORK_BODY_CAPTURE_BYTES=1048576 ``` `CLOAKFETCH_HOST` 默认是 `0.0.0.0`,也可以设置为 `127.0.0.1` 或具体 IPv4/IPv6 地址。 默认 source profile 路径是: ```text profile/sources/ ``` 所有项目内部路径都相对于项目根目录,不依赖启动时的当前工作目录。`profile/` 是运行数据,不应打包、上传或提交。 当前 CloakBrowser 版本在部分平台会把带认证代理转成 Chromium 命令行参数,因此 `CLOAKFETCH_PROXY` 中包含 username/password 时会在启动阶段被拒绝,错误码为 `proxy_auth_not_supported`。建议把 Mihomo 或其他上游代理暴露成本地无认证端口,例如 `http://127.0.0.1:7890`。 ## 基础 API `GET /health` ```json { "status": "ok" } ``` `POST /v1/fetch` ```json { "source_id": "default", "url": "https://example.com/file.png", "headers": { "Referer": "https://example.com/" }, "timeout_ms": 30000, "cache_mode": "default" } ``` 未传 `source_id` 时使用 `default` SourceSession。响应状态码来自目标站,响应体是目标二进制内容。额外响应头: ```text x-cloakfetch-final-url x-cloakfetch-fetch-mode ``` `cache_mode`: - `default`:允许 Chromium 使用正常缓存语义。 - `reload`:禁用当前页面缓存。 - `/v1/diagnostics/fetch` 会强制使用 `reload`,避免缓存影响代理和目标站诊断。 调用方传入的 headers 只应用到第一次主文档导航请求。页面后续 script、style、image、iframe、xhr、fetch、websocket 等请求完全由 Chromium 自己生成。 响应大小会先检查 `Content-Length`;没有 `Content-Length` 的响应只能在读取完成后检查实际大小,当前版本不支持真正流式限速。 `POST /v1/diagnostics/fetch` 返回 JSON 诊断信息,不返回二进制 body: ```json { "url": "https://example.com/file.jpg", "final_url": "https://example.com/file.jpg", "status": 200, "ok": true, "content_type": "image/jpeg", "body_size": 44891, "elapsed_ms": 421, "fetch_mode": "document", "error": null } ``` `GET /v1/stats` ```json { "lifetime_total": 12, "lifetime_failed": 1, "active": 0, "queued": 0 } ``` ## SourceSession API `default` SourceSession 会自动存在。每个 SourceSession 拥有独立 BrowserContext、独立 profile、独立 Cookie、缓存、LocalStorage、IndexedDB 和 Service Worker。 `POST /v1/sources` ```json { "id": "arcgis", "warmup_url": "https://www.arcgis.com/", "locale": "zh-CN", "viewport": { "width": 1920, "height": 1080 } } ``` `POST /v1/sources/:id/warmup` ```json { "url": "https://www.arcgis.com/", "wait_until": "domcontentloaded", "timeout_ms": 30000 } ``` 其他 source API: ```text GET /v1/sources GET /v1/sources/:id DELETE /v1/sources/:id GET /v1/sources/:id/cookies GET /v1/sources/:id/pages ``` `source_id` 只用于路径名称映射,只允许字母、数字、点、下划线和短横线。 ## Network Observer Chromium 内部网络事件使用独立 ring buffer,和外层 `/v1/fetch` 请求历史分开。默认保留最近 10000 条,可通过 `CLOAKFETCH_NETWORK_HISTORY_LIMIT` 调整。 记录字段包括: ```text id, source_id, page_id, request_id, parent_request_id, started_at, finished_at, duration_ms, url, method, resource_type, navigation, frame_url, initiator, request_headers, request_body_size, request_post_data, status, status_text, protocol, response_headers, response_body_size, mime_type, remote_address, from_cache, service_worker, failure_text, redirect_from, redirect_to ``` 请求头、响应头和 post data 默认完整记录。`CLOAKFETCH_NETWORK_BODY_CAPTURE_BYTES` 只限制观测存储大小,不限制真实请求。 ```text 0 = 不抓取 body 内容,只记录大小 -1 = 不限制抓取大小 ``` Network API: ```text GET /v1/network/recent GET /v1/network/:id GET /v1/network/:id/body GET /v1/network/summary DELETE /v1/network/history ``` `GET /v1/network/recent` 支持: ```text limit, source_id, page_id, method, resource_type, status, host, failed, from_cache, text ``` `GET /v1/network/summary` 返回 retained、active、finished、failed、method/resource/status/host/protocol 分布、cache hit、字节数和耗时统计。 `DELETE /v1/network/history` 只清空观测历史,不关闭 BrowserContext。 ## WebSocket `GET /v1/ws` ```js const ws = new WebSocket("ws://127.0.0.1:9230/v1/ws"); ws.onmessage = event => console.log(JSON.parse(event.data)); ``` 消息格式: ```json { "version": 1, "sequence": 123, "type": "network.finished", "time": "2026-07-24T12:00:00.000Z", "data": {} } ``` 事件类型: ```text hello heartbeat request source.created source.starting source.ready source.failed source.removed page.created page.closed network.request network.response network.finished network.failed browser.console browser.pageerror browser.crash ``` 不提供 SSE,不提供 Socket.IO。 ## Web Console 构建后由 Fastify 托管: ```powershell npm run build npm run start ``` 访问: ```text http://127.0.0.1:9230/console http://<服务器局域网IP>:9230/console ``` 控制台包含: - Runtime 状态和代理状态 - Source Sessions 状态、Warmup、Remove、Open pages、View cookies - 外层 Request Log - Network Inspector - Network 过滤、详情、Pause live update、Clear local view、清空服务端 network history Network WebSocket 事件在前端按 150ms 批量合并,前端最多保留 5000 条 network record。 开发模式: ```powershell npm run dev npm run web:dev ``` 如果 `web/dist` 不存在,`/console` 返回 `console_not_built` 的 404 JSON,不影响 `/health` 和 `/v1/*` API。