Qiyuan SDK 接口文档
指纹浏览器 · 自包含 Python SDK + 管理后台 · v2.1
概述与架构
本 SDK 将服务端接口与本地客户端接口拆分维护。服务端使用 browser-config-server.json,客户端使用 browser-config-client.json;客户端启动时会在浏览器应用数据目录生成 config/config.json,并通过 base_api_path 访问服务端。
base_api_path 承载服务端接口,base_local_api_path 承载本地客户端接口,生成的 browser_base_path 使用 base_api_path 的值。导航中的 标识服务端接口。
- 环境 / 代理管理 / 插件:由服务端接口承载;自包含运行时数据由服务端持久化,查看具体数据表结构。
- 本地浏览器控制:
open/close/status/clear_cache直接拉起 / 终止本机真实浏览器进程。
每个接口都有对应的 HTTP 路由,二者共享同一份逻辑。标签说明:服务 为服务端操作,本地 为本机进程操作。
自研产品 / 调用方
用户界面、业务流程和用户体系。通过 HTTP 调用 SDK 接口。
SDK 服务端
环境、代理、扩展管理接口;服务端数据库;向客户端提供共享数据。
SDK 客户端 + 浏览器内核
本地打开、关闭和管理浏览器进程;运行 Chromium 或 Firefox 内核。
接入方式
管理后台基于 HTTP 协议。服务端默认监听 http://127.0.0.1:9003,客户端默认监听 http://127.0.0.1:9005。本 SDK 提供单机部署和分离部署两种方式,二者使用相同的服务端启动与客户端启动步骤。
- 单机部署:在同一台机器分别启动服务端和客户端,适合开发调试、演示和单机使用。
- 分离部署:服务端和客户端部署在不同机器,服务端集中管理环境、代理和扩展,客户端在用户电脑上启动本地浏览器。
准备工作
首先联系
拿到 SDK 源码、客户端程序和对应的 Chromium / Firefox 内核 ZIP。源码目录应包含 admin、sdk、browser-config-server.json 和 browser-config-client.json。
内核不需要放入源码目录。客户端启动后,在“系统设置”中选择内核类型和版本并上传 ZIP,程序会将内核安装到浏览器应用数据目录的 client/<版本> 下。
qiyuanbrowser/ ├── admin/ ├── sdk/ ├── dist/ │ └── QiyuanSDKClient.exe # 已打包的客户端程序 ├── browser-config-server.json ├── browser-config-client.json └── ...
dist/QiyuanSDKClient.exe 是客户端启动程序的打包版本,功能等价于 python -m admin.client。它不包含浏览器内核,启动时通过 --config 指定客户端配置文件;适合随自研产品一起分发并独立启动。
两种内核的版本号均需与 browser-config-client.json 中配置的一致。
单机部署接入操作步骤
- 在 SDK 根目录安装 Python 依赖:
cd qiyuanbrowser pip install -r requirements.txt python -m admin.server --config browser-config-server.json python -m admin.client --config browser-config-client.json
服务端和客户端都启动后,打开 http://127.0.0.1:9005/ 进入客户端管理页面,在“系统设置”上传 Chromium 或 Firefox 内核 ZIP。内核最终位置示例:%USERPROFILE%\.qiyuan\client\153.0.4。
分离部署接入操作步骤
适合将用户体系与业务界面放在自研产品中,由 SDK 服务端集中管理环境、代理和扩展,由安装在用户电脑上的 SDK 客户端启动浏览器。终端用户先登录自研产品,再通过产品操作自己的浏览器环境。
打开/关闭窗口
状态与内核回调
1. 服务端
服务端只保存和管理环境、代理、扩展等数据,不负责启动本地浏览器。使用 browser-config-server.json 执行:
cd qiyuanbrowser pip install -r requirements.txt python -m admin.server --config browser-config-server.json
2. 客户端
在 browser-config-client.json 中将 base_api_path 设置为服务端地址,例如 http://服务端IP:9003,将 base_local_api_path 设置为本机客户端地址(例如 http://127.0.0.1:9005)。客户端有两种启动方式,二选一:
方式 A:源码启动
cd qiyuanbrowser pip install -r requirements.txt python -m admin.client --config browser-config-client.json
方式 B:QiyuanSDKClient.exe 启动(客户端程序请联系官网客服获取)
QiyuanSDKClient.exe --config browser-config-client.json
EXE 启动方式等价于源码启动方式,只替换了启动程序。启动后访问 http://127.0.0.1:9005/,进入“系统设置”,上传对应内核 ZIP;内核会安装到 %USERPROFILE%\.qiyuan\client\<版本>,例如 %USERPROFILE%\.qiyuan\client\153.0.4。
如果开发自研产品,可以将 QiyuanSDKClient.exe 随产品附带并独立启动本地客户端服务。服务端仍通过 base_api_path 提供环境、代理和扩展数据。
请求说明
- GET 接口:参数通过 URL Query String 传递
- POST 接口:参数通过 JSON Body 传递,请求头需包含
Content-Type: application/json
测试与验证
直接测试接口:进入 SDK 源码目录的 tests 目录运行测试脚本。UI 测试:同时启动服务端和客户端后,访问客户端地址 http://127.0.0.1:9005/;服务端管理接口地址为 http://127.0.0.1:9003/。
接口规格
请求格式
GET 接口使用 URL Query 参数;普通 POST 接口使用 JSON Body,并设置 Content-Type: application/json。扩展新增/修改接口使用 multipart/form-data,文本字段与 ZIP 文件通过表单提交;客户端回调按各接口说明提交 JSON。
请求 Content-Type:GET 无请求体;环境、代理及普通扩展操作使用 application/json;扩展新增、修改使用 multipart/form-data。当前源码实际存在以下响应类型:
{ "success": true, "data": { /* 业务数据 */ } }
{ "success": false, "error": "错误描述" }
有业务结果时放入 data;修改、删除等仅确认完成的接口实际返回 { "success": true },没有 data 字段。
{ "code": 200, "message": "OK", "data": { /* 业务数据 */ }, "success": true }
{ "code": 400, "message": "错误描述", "data": null, "success": false }
{ "success": true, "ip": "203.0.113.10", "latency_ms": 85, ... }
{ "success": false, "error": "检测失败原因" }
客户端设置接口 Local
仅 client / all 模式可用。读取当前客户端使用的共享 Token,用于初始化系统设置页面。
响应示例
{ "success": true, "data": { "token": "your-token" } }仅 client / all 模式可用。更新客户端本地 Token,不修改服务端 Token。
JSON 参数
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| token | string | 必填 | 新的共享 Token |
响应示例
{ "success": true, "data": { "updated": true } }仅 client / all 模式可用,使用 multipart/form-data。内核只保存到浏览器应用数据目录。
表单参数
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| kernel | string | 必填 | chrome 或 firefox |
| version | string | 必填 | 内核版本号 |
| file | ZIP | 必填 | 用户选择对应内核 ZIP |
| set_default | boolean | 可选 | 是否设为默认版本;同版本允许覆盖,运行中禁止覆盖 |
响应示例
{ "success": true, "data": { "kernels": { "chrome": { "installed_versions": ["150.0.7871.116"] } } } }数据表结构
以下为服务端 SQLite 中的业务数据表结构。客户端运行配置不属于 SaaS 业务表;字段约束和默认值以当前 SDK 初始化脚本为准,JSON 字段以文本形式存储,接口返回时解析为对象或数组。
environments · 环境表
| 字段 | 类型 | 约束 | 默认 | 说明 |
|---|---|---|---|---|
| id | INTEGER | 主键,自增 | — | 内部记录 ID |
| code | TEXT | 唯一,必填 | — | 环境唯一标识 |
| name | TEXT | 必填 | — | 环境名称 |
| platform | TEXT | 必填 | Win32 | 系统平台 |
| browser_version | TEXT | 可空 | NULL | 内核版本 |
| browser_kernel | TEXT | 必填 | chrome | chrome / firefox |
| user_agent | TEXT | 可空 | NULL | User-Agent |
| proxy_code | TEXT | 可空 | NULL | 绑定代理 code |
| proxy_mode | TEXT | 必填 | no_proxy | no_proxy / existing / custom |
| custom_proxy_type | TEXT | 可空 | NULL | 自定义代理类型 |
| custom_proxy_addr | TEXT | 可空 | NULL | 自定义代理地址 |
| custom_proxy_port | INTEGER | 可空 | NULL | 自定义代理端口 |
| custom_proxy_username / password | TEXT | 可空 | NULL | 自定义代理认证 |
| proxy_input_type | TEXT | 可空 | NULL | manual / api |
| proxy_api_url | TEXT | 可空 | NULL | 代理 API 地址 |
| open_home_page | INTEGER | 非空 | 0 | 是否打开首页 |
| enable_tabs | INTEGER | 非空 | 0 | 是否启用标签页 |
| tabs | TEXT | 非空 | 空字符串 | 标签页数据 |
| sync_user_info | INTEGER | 非空 | 0 | 是否同步用户信息 |
| cookie | TEXT | 非空 | 空字符串 | Cookie 配置 |
| launch_args | TEXT | 非空 | 空字符串 | 启动参数 |
| remark | TEXT | 非空 | 空字符串 | 备注 |
| tag_ids | TEXT (JSON) | 非空 | [] | 标签 ID 列表 |
| fingerprint | TEXT (JSON) | 非空 | {} | 指纹配置 |
| pid / debug_port | INTEGER | 可空 | NULL | 进程 ID 与调试端口 |
| create_time / update_time | TEXT | 必填 | — | 创建和更新时间 |
proxies · 代理表
| 字段 | 类型 | 约束 | 默认 | 说明 |
|---|---|---|---|---|
| id | INTEGER | 主键,自增 | — | 内部记录 ID |
| code | TEXT | 唯一,必填 | — | 代理唯一标识 |
| proxy_name | TEXT | 必填 | — | 代理名称 |
| proxy_type | TEXT | 必填 | — | http / https / socks5 |
| proxy_addr | TEXT | 必填 | — | 代理地址 |
| proxy_port | INTEGER | 必填 | — | 代理端口 |
| username / password | TEXT | 非空 | 空字符串 | 代理认证 |
| proxy_input_type | TEXT | 非空 | manual | manual / api |
| proxy_api_url | TEXT | 可空 | NULL | 代理 API 地址 |
| remark | TEXT | 非空 | 空字符串 | 备注 |
| create_time / update_time | TEXT | 必填 | — | 创建和更新时间 |
extensions · 扩展表
| 字段 | 类型 | 约束 | 默认 | 说明 |
|---|---|---|---|---|
| id | INTEGER | 主键,自增 | — | 内部记录 ID |
| code | TEXT | 唯一,必填 | — | 扩展唯一标识 |
| name / version | TEXT | 必填 | — | 名称与版本 |
| browser_kernel | TEXT | 非空 | chrome | chrome / firefox |
| extension_type | TEXT | 非空 | normal | normal / builtin |
| provider / source_url / description | TEXT | 非空 | 空字符串 | 来源与说明 |
| file_name / file_path / oss_key | TEXT | 非空 | 空字符串 | 文件及 OSS 存储信息 |
| sha256 | TEXT | 非空 | 空字符串 | 文件校验值 |
| file_size | INTEGER | 非空 | 0 | 文件大小 |
| icon_path | TEXT | 非空 | 空字符串 | 图标路径 |
| status | INTEGER | 非空 | 1 | 1 启用,0 停用 |
| create_time / update_time | TEXT | 必填 | — | 创建和更新时间 |
扩展与环境的绑定保存在 extension_bindings,扩展同步结果保存在 extension_sync_state;这两张关联表用于支持“全部环境/指定环境”和同步状态,不属于扩展主表字段。
browser_errors · 浏览器错误表
| 字段 | 类型 | 约束 | 默认 | 说明 |
|---|---|---|---|---|
| id | INTEGER | 主键,自增 | — | 内部记录 ID |
| code | TEXT | 唯一,必填 | — | 错误记录唯一标识 |
| title | TEXT | 必填 | — | 错误标题 |
| detail / type | TEXT | 可空 | NULL | 错误详情与类型 |
| create_time | TEXT | 必填 | — | 创建时间 |
extension_bindings · 扩展环境绑定表
| 字段 | 类型 | 约束 | 默认 | 说明 |
|---|---|---|---|---|
| id | INTEGER | 主键,自增 | — | 内部记录 ID |
| extension_code | TEXT | 必填 | — | 扩展 code |
| environment_code | TEXT | 必填 | — | 环境 code;* 表示全部环境 |
| create_time | TEXT | 必填 | — | 绑定时间 |
| extension_code + environment_code | — | 联合唯一 | — | 避免重复绑定 |
extension_sync_state · 扩展同步状态表
| 字段 | 类型 | 约束 | 默认 | 说明 |
|---|---|---|---|---|
| id | INTEGER | 主键,自增 | — | 内部记录 ID |
| environment_code / extension_code | TEXT | 必填 | — | 环境与扩展标识 |
| version | TEXT | 必填 | — | 已同步版本 |
| target_path | TEXT | 必填 | — | 本地目标路径 |
| sha256 | TEXT | 非空 | 空字符串 | 已同步文件校验值 |
| sync_status | TEXT | 非空 | success | 同步状态 |
| error_message | TEXT | 非空 | 空字符串 | 失败原因 |
| synced_at | TEXT | 必填 | — | 同步时间 |
| environment_code + extension_code | — | 联合唯一 | — | 每个环境扩展仅保留一条状态 |
环境接口 Environment
Query 参数
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| page | number | 可选 | 页码,默认 1 |
| page_size | number | 可选 | 每页数量,默认 20 |
| keyword | string | 可选 | 按名称 / 备注 / code 模糊搜索 |
响应示例
{
"success": true,
"data": {
"total": 100,
"page": 1,
"page_size": 20,
"items": [
{
"code": "a1b2c3d4...", // string 环境唯一标识,后续操作均使用此字段
"name": "测试账号-01",
"platform": "Win32", // Win32 / MacIntel / Linux x86_64
"browser_kernel": "chrome", // chrome(Chromium)/ firefox
"browser_version": "150.0.7871.115",
"user_agent": "Mozilla/5.0 ...",
"proxy_code": "1716523...", // 绑定代理的唯一标识,未绑定为 null
"open_home_page": false,
"remark": "备注信息",
"tag_ids": [1, 2],
"status": "stopped", // running | stopped
"pid": null, // 进程 pid,running 时有值
"create_time": "2026-01-01 00:00:00",
"update_time": "2026-06-01 12:00:00"
}
],
"total_pages": 5
}
}
| 字段 | 类型 | 必填 | 默认值 | 说明 |
|---|---|---|---|---|
| name | string | 必填 | — | 环境名称 |
| platform | string | 可选 | Win32 | Win32 / MacIntel / Linux x86_64 |
| browser_kernel | string | 可选 | chrome | chrome(Chromium)或 firefox;版本须属于所选内核 |
| browser_version | string | 可选 | 最新版本 | 完整内核版本号,不填取默认 |
| user_agent | string | 可选 | 自动生成 | 不填时按 platform + browser_version 自动生成 |
| proxy_code | string | 可选 | 绑定代理的 code(来自 GET /open/proxy/list) | |
| fingerprint | object | 可选 | 自动随机 | 不填时按 platform 自动生成随机指纹 |
| open_home_page | boolean | 可选 | false | 是否打开起始页 |
| enable_tabs | boolean | 可选 | false | 是否启用标签页 |
| tabs | string | 可选 | "" | 标签页 URL,换行分隔,最多 5 个(enable_tabs=true 生效) |
| sync_user_info | boolean | 可选 | false | 是否同步用户信息 |
| cookie | string | 可选 | "" | 初始 Cookie(JSON 数组) |
| launch_args | string | 可选 | "" | 额外 Chrome 启动参数,空格分隔 |
| remark | string | 可选 | "" | 备注 |
| tag_ids | number[] | 可选 | [] | 标签 ID 列表 |
指纹字段(均可选,表单风格;不传走随机默认)
| 字段 | 类型 | 可选值 / 说明 |
|---|---|---|
| user_agent | string | 不填按 platform + browser_version 自动生成 |
| webrtc | string | ip / real / disabled / transform_google |
| webgl | string | real / custom;custom 时配合 webgl_vendor + webgl_renderer |
| webgpu | string | basegl / real / custom;custom 时配合 webgpu_vendor/architecture/device/description |
| timezone | string | ip / real / custom;custom 时配合 timezone_value(如 Asia/Shanghai) |
| geo_location | string | ip / real / custom;custom 时配合 longitude + latitude |
| language | string | ip / real / custom;custom 时配合 languages(string[]) |
| ui_language | string | language / real / custom;custom 时配合 ui_language_value |
| screen_resolution | string | real / custom;custom 时配合 screen_resolution_value(如 1920|1080) |
| font / canvas / audio / client_rects | string | random(随机偏移)/ disabled(0) |
| speech_voices | boolean | 是否开启 |
| media_devices | string | random / disabled |
| cpu_cores / memory_gb | string | real 或具体数值(如 8 / 16) |
| tls | string | disabled / enabled;enabled 时配合 tls_features(string[]) |
响应示例
{ "success": true, "data": { "code": "新环境的唯一标识" } }
返回单个环境的完整字段 + 扁平指纹,供编辑表单回填。
Query 参数
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| code | string | 必填 | 环境唯一标识 |
响应示例
{
"success": true,
"data": {
"code": "...", "name": "...", "platform": "Win32",
"browser_kernel": "chrome",
"browser_version": "147.0.7727.102", "user_agent": "...",
"proxy_code": null, "open_home_page": false,
"enable_tabs": false, "tabs": "", "sync_user_info": false,
"cookie": "", "launch_args": "", "remark": "",
"fingerprint": { /* 扁平指纹:webgl_type, webgl_value, timezone_type, ... */ }
}
}
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| code | string | 必填 | 环境唯一标识 |
| browser_kernel | string | 可选 | chrome(Chromium)或 firefox;变更内核时需选择该内核支持的版本 |
| browser_version | string | 可选 | 所选内核的完整版本号 |
| 基础字段 + 指纹字段(同 新增环境) | — | 可选 | 需要修改的字段;传入的指纹字段会合并进已存指纹。修改 platform / browser_version 且未显式传 user_agent 时自动重新生成 UA |
响应示例
{ "success": true }
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| code | string | 必填 | 环境唯一标识 |
响应示例
data 为新生成的指纹对象。
{ "success": true, "data": { "webgl_vendor": "Google Inc. (Intel)", "canvas": "random" } }
删除环境记录,并自动关闭其运行中的浏览器、清理本地缓存目录。
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| code | string | 必填 | 环境唯一标识 |
响应示例
{ "success": true }
client 模式启动:以 --mode=client --uuid={code} --token={token} 拉起启元定制内核(路径 %USERPROFILE%\.qiyuan\client\{browser_version}\QyBrowser.exe,user-data-dir = %USERPROFILE%\.qiyuan\user_data\{uuid})。不再传 --user-agent / --proxy-server / --remote-debugging-port——浏览器自身回调 GET /api/v1/browser/md5/{uuid} 拉取并解密指纹后内部应用。打开前 SDK 会把 admin 服务地址写入 config.json 的 base_api_path。
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| code | string | 必填 | 环境唯一标识(即 uuid) |
| openTabs | boolean | 可选 | 是否按环境配置打开标签页,默认 false |
| needDebugPort | boolean | 可选 | 是否分配并等待 CDP 调试端口,默认 true。设为 false 时响应 debug_port 为 null |
| args | string[] | 可选 | 额外启动参数 |
响应示例
{ "success": true, "data": { "pid": 12345, "debug_port": 19222, "browser_kernel": "chrome", "debug_protocol": "cdp" } }
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| code | string | 必填 | 环境唯一标识;未运行时返回错误 |
Query 参数
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| code | string | 必填 | 环境唯一标识 |
响应示例
{ "success": true, "data": { "code": "...", "status": "running", "pid": 12345 } }
删除该环境的本地 user-data-dir 缓存目录。若浏览器正在运行会先关闭。
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| code | string | 必填 | 环境唯一标识 |
代理接口 Proxy
Query 参数
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| page | number | 可选 | 页码,默认 1 |
| page_size | number | 可选 | 每页数量,默认 20 |
| keyword | string | 可选 | 按名称 / 地址 / code 模糊搜索 |
响应示例
{
"success": true,
"data": {
"total": 3,
"page": 1,
"page_size": 20,
"total_pages": 1,
"items": [
{
"code": "f3a9...",
"proxy_name": "美国节点",
"proxy_type": "http", // http / https / socks5
"proxy_addr": "1.2.3.4",
"proxy_port": 8080,
"proxy_input_type": "manual"
}
]
}
}
Query 参数
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| code | string | 必填 | 代理唯一标识 |
响应示例
{ "success": true, "data": { "code": "f3a9...", "proxy_name": "美国节点", "proxy_type": "http", "proxy_addr": "1.2.3.4", "proxy_port": 8080 } }| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| proxy_name | string | 必填 | 代理名称 |
| proxy_type | string | 必填 | http / https / socks5 |
| proxy_addr | string | 必填 | 代理地址 |
| proxy_port | number | 必填 | 代理端口 |
| username | string | 可选 | 账号 |
| password | string | 可选 | 密码 |
| remark | string | 可选 | 备注 |
响应示例
{ "success": true, "data": { "code": "新代理的唯一标识" } }
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| code | string | 必填 | 代理唯一标识 |
| proxy_name / proxy_type / proxy_addr / proxy_port / username / password / remark | — | 可选 | 需要修改的字段 |
响应示例
{ "success": true }
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| code | string | 必填 | 代理唯一标识 |
响应示例
{ "success": true }
客户端回调接口 Client
这些接口由 --mode=client 启动的浏览器(而非调用方)回调,admin server 提供实现。鉴权 token 即 env_open 传给浏览器的那一个。/api/v1/* 使用后端风格信封 {code,message,data,success};/api/* 使用本地风格 {success,...}。
鉴权:Authorization: Bearer {token}。返回加密后的指纹(base64 字符串)。
Query 参数
| 字段 | 类型 | 默认 | 说明 |
|---|---|---|---|
| secure | boolean | true | 是否加密(安全)。false 返回明文,encrypt_type 忽略 |
| encrypt_type | string | aes | 加密方式:aes / rsa(rsa 为 AES 加密 + RSA 签名) |
| version | string | 1.0 | 算法版本(便于后续升级)。2.0 且 encrypt_type=aes 时启用按 token 派生的密钥(见下);rsa 恒用该派生密钥 |
响应
{ "code": 200, "success": true, "data": "<base64 密文 或 明文对象>" }
解密方式 · AES(默认)
base64 解码 → 前 16 字节为 IV → AES-256-CBC / PKCS7 → 指纹 JSON 明文。
version=1.0(默认)密钥:字符串 aes-key-32-bytes-change!!!!! 末尾补 \0 到 32 字节。
version=2.0 密钥:SHA-256( "aes-key-32-bytes-change!!!!!" + "_qiyuan_" + 用户认证token ) 的 32 字节摘要(token 即请求头 Bearer)。每用户唯一;内核须用同一算法派生密钥。
解密方式 · RSA(encrypt_type=rsa,AES 加密 + RSA 签名)
密文 = base64( SIGN[keysize/8] + IV[16] + AES-256-CBC(PKCS7(json)) )。其中 SIGN = RSASSA-PKCS1-v1_5( 私钥, SHA-256( IV+密文 ) )(2048-bit = 256 字节)。AES 密钥恒用 version=2.0 的 token 派生密钥。
内核侧:base64 解码 → 前 256 字节为签名、其余为 IV+密文 → 用内置公钥 SHA-256 验签(失败即拒绝,不解密)→ 用 token 派生 AES key 解出 16 字节 IV 与密文 → AES-CBC 得 JSON。
方向:服务端持私钥签名,内核仅内置公钥验签,私钥永不下发。SDK 与 backend 各自独立密钥对(PEM 随仓库提供:SDK sdk/keys/、backend app/config/keys/;只把对应 rsa_public.pem 编入内核)。
明文结构(节选)
{
"platform": "Win32",
"user_agent": "Mozilla/5.0 ...",
"browser_version": "147.0.7727.102",
"webgl": { "type": "custom", "value": "Google Inc. (NVIDIA)|ANGLE (NVIDIA, NVIDIA GeForce RTX 4070 Ti Direct3D11 vs_5_0 ps_5_0, D3D11)" },
"webgpu": { "type": "custom", "value": "nvidia|..." },
"timezone": { "type": "ip", "value": null },
"language": { "type": "ip", "value": null },
"geo_location": { "type": "ip", "value": null },
"hardware_info": { "color_depth": "24", "cpu_cores": "8", "memory_gb": "8" },
"font": "1", "canvas": "0.37", "audio": "42",
"speech_voices": true, "media_devices": ["a1b2..."],
"open_home_page": false, "enable_tabs": false, "tabs": "",
"cookie": "", "launch_args": "",
"proxy_info": { "proxy_type": "http", "proxy_addr": "1.2.3.4", "proxy_port": "8080", "username": "u", "password": "p" }
}
无需 token。
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| title | string | 必填 | 错误标题 |
| detail | string | 可选 | 错误详情 |
| type | string | 可选 | 错误类型 |
响应
{ "code": 200, "success": true, "data": { "code": "a1b2c3d4" } } // code 用于拼错误页
仅当该环境 enable_tabs=true 时保存;按域名去重、跳过起始页/内部地址(chrome://、about: 等)、最多 5 条。
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| md5 | string | 必填 | 环境唯一标识(uuid) |
| tabs | string | 必填 | 换行分隔的 URL 列表 |
经该代理访问 geo 服务,返回与 ip-geo 兼容的结构。
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| proxy_type | string | 必填 | http / https / socks5 |
| proxy_addr | string | 必填 | 代理地址 |
| proxy_port | number | 必填 | 代理端口 |
| username / password | string | 可选 | 认证信息 |
响应
{ "success": true, "ip": "1.2.3.4", "country_code": "US",
"latitude": 37.7, "longitude": -122.4,
"timezone": { "id": "America/Los_Angeles" } }
鉴权:Authorization: Bearer {token}。
Query 参数
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| ip | string | 可选 | 留空查询出口 IP |
响应
同 check-proxy(success / ip / country_code / latitude / longitude / timezone.id …)。
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| uuid | string | 必填 | 环境唯一标识 |
| status | string | 必填 | opened | closed |
响应
{ "success": true }
扩展接口 Extensions
扩展管理接口由服务端提供,数据由服务端持久化。新增和修改使用 multipart/form-data 上传 ZIP,并可通过 environment_codes 绑定一个或多个环境;传入 ["*"] 表示全部环境。
Query 参数
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| page | number | 可选 | 页码,默认 1 |
| page_size | number | 可选 | 每页数量,默认 20 |
| keyword | string | 可选 | 按名称、code、提供方搜索 |
| browser_kernel | string | 可选 | chrome / firefox;不传则全部 |
| extension_type | string | 可选 | builtin / normal;不传则全部 |
响应示例
{ "success": true, "data": { "items": [{ "code": "demo", "name": "示例扩展", "version": "1.0", "browser_kernel": "chrome", "extension_type": "normal", "environment_codes": ["*"] }], "total": 1, "page": 1, "page_size": 20, "total_pages": 1 } }Query 参数
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| code | string | 必填 | 扩展唯一标识 |
响应示例
{ "success": true, "data": { "code": "demo", "name": "示例扩展", "version": "1.0", "browser_kernel": "chrome", "extension_type": "normal", "status": 1, "environment_codes": ["*"] } }请求类型:multipart/form-data。
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| code | string | 必填 | 扩展唯一标识,只能包含字母、数字、下划线、短横线 |
| name | string | 必填 | 扩展名称 |
| version | string | 必填 | 扩展版本 |
| file | ZIP 文件 | 必填 | 需包含 manifest.json |
| browser_kernel | string | 可选 | chrome(默认)/ firefox |
| extension_type | string | 可选 | normal(默认)/ builtin |
| environment_codes | JSON 数组字符串 | 可选 | 环境 code 列表;["*"] 为全部,空数组为不绑定 |
| provider / source_url / description | string | 可选 | 提供方、来源地址、说明 |
响应示例
{ "success": true, "data": { "code": "demo", "name": "示例扩展", "version": "1.0", "environment_codes": ["*"] } }请求类型:multipart/form-data。
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| code | string | 必填 | 要修改的扩展 code,不可修改 |
| name / version / provider / source_url / description | string | 可选 | 需要修改的字段 |
| browser_kernel | string | 可选 | chrome / firefox |
| extension_type | string | 可选 | normal / builtin |
| status | number | 可选 | 1 启用,0 停用 |
| environment_codes | JSON 数组字符串 | 可选 | 新的环境绑定;["*"] 为全部 |
| file | ZIP 文件 | 可选 | 上传新包以升级扩展 |
响应示例
{ "success": true, "data": { "code": "demo", "version": "1.1", "environment_codes": ["*"] } }JSON 参数
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| code | string | 必填 | 要删除的扩展 code |
响应示例
{ "success": true, "data": { "code": "demo" } }JSON 参数
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| code | string | 必填 | 扩展 code |
| environment_codes | string[] | 可选 | 环境 code 列表;["*"] 为全部,空数组为取消绑定 |
| bind_all | boolean | 可选 | 为 true 且未提供环境列表时绑定全部 |
响应示例
{ "success": true, "data": { "code": "demo", "environment_codes": ["*"] } }JSON 参数
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| code | string | 必填 | 需要同步扩展的环境 code;环境打开前也会自动同步 |
响应示例
{ "success": true, "data": [{ "code": "demo", "status": "success", "target_path": "..." }] }扩展类型与同步路径
browser_kernel=chrome 表示 Chromium,browser_kernel=firefox 表示 Firefox。extension_type=builtin 为内置扩展,normal 为普通扩展。
| 内核 | 内置(builtin) | 普通(normal) |
|---|---|---|
| Chromium | %browser_app_data_dir%/extends/<code> | %browser_app_data_dir%/user_data/<environment_code>/Default/custom_extensions/<code> |
| Firefox | %browser_app_data_dir%/client/<fire_version>/custom-extensions/<code> | %browser_app_data_dir%/user_data/<environment_code>/extensions/<code> |
环境启动前会自动同步已绑定且启用的扩展;升级会覆盖旧目录,解除绑定或删除扩展会清理对应目录。同步接口返回标准 success/data 响应。
起始页 / 错误页 Pages
由 admin server 直接托管(无需扩展)。内核通过 config.json 的 browser_base_path 拼出页面地址:{browser_base_path}/pages/home.html?md5={uuid} 与 {browser_base_path}/pages/error.html?code={code}。页面与 admin 同源,直接 fetch 下方数据接口。env_open 时 SDK 会把 base_api_path 与 browser_base_path 一并写入 config.json。
开启起始页时浏览器加载的页面:顶部 IP 检测横幅 + 环境信息 + 指纹信息。Query:md5(环境唯一标识)。有代理时通过 check-proxy 进行检测。
启动异常时浏览器加载的页面,展示错误编号 / 标题 / 时间。Query:code(错误编号,来自 error/report)。
无需 token。返回 { browser, fingerprint, proxy } 三段(中文化展示值)。
{ "code": 200, "success": true, "data": {
"browser": { "name": "...", "proxy_mode_cn": "集成代理", "sync_user": "关闭", ... },
"fingerprint": { "platform": "Windows", "webgl": "自定义 - NVIDIA / RTX 4090", ... },
"proxy": { "proxy_mode": "existing", "proxy_addr": "1.2.3.4", "proxy_port": 8080, ... }
} }
无需 token。
{ "code": 200, "success": true, "data": { "code": "a1b2c3d4", "title": "启动失败", "error_time": "2026-06-24 12:00:00" } }