domains007
v1.0.13
Published
API domain configuration with base64 encoding for Android app failover
Maintainers
Readme
domains007
Base64 编码的 API 域名配置包,用于 Android App 域名容灾。
核心思路
用 npm + CDN 作为免费、高可用的域名配置分发通道,让 Android App 在域名挂了的时候能自我修复。
域名挂了时(你的操作):
python3 publish.py → 自动拉接口 → 生成 domains.json → npm publish
│
▼
jsdelivr / unpkg CDN 自动更新(1-5分钟)
│
▼
Android App:
KeepAlive.init(...) + KeepAlive.failoverInterceptor()
│
├─ 1. 用当前域名发起 okhttp 请求
├─ 2. 域名实效 → 拦截器同步切换
├─ 3. CDN 拉取 domains.json → base64 解码 → 获得新域名
├─ 4. 新域名测速通过 → 切换 → 自动重试
└─ 5. SharedPreferences 缓存最新域名为什么这个方案成立
npm + CDN(unpkg / jsdelivr)的基础设施可用性远超你自己某个 API 域名:
| 渠道 | 被墙/挂掉概率 | 速度 | 成本 |
| ------ | :---------: | ------ | ------ |
| 你自己的 API 域名 | 高(这就是问题) | — | 服务器成本 |
| npmjs.com | 极低 | 全球 CDN | 免费 |
| unpkg.com | 极低 | Cloudflare | 免费 |
| jsdelivr.net | 极低(国内可用) | 全球 + 国内节点 | 免费 |
App 同时配 3 个 CDN 地址作为 fallback,几乎不可能全挂。
项目结构
domains/
├── package.json # name=domains007, version
├── domains.json # ★ 核心:base64 编码的域名配置(发布到 npm)
├── index.js # CommonJS 入口,自动解码
├── index.mjs # ESM 入口
├── index.d.ts # TypeScript 类型定义
├── publish.py # 一键发布脚本(本地工具,不入库)
├── encode.js # 旧的手动编码脚本(已被 publish.py 取代)
├── .npmignore
└── README.md关键设计
| 设计点 | 实现 |
| ------ | ------ |
| 域名不暴露 | domains.json 的 payload 是 base64 编码的 JSON,CDN 上浏览看不到明文 |
| 多渠道 | 按 channels 区分不同产品,一个 App 一个 channel |
| 多 CDN 容灾 | jsdelivr + jsdelivr@latest + unpkg,三个地址依次尝试 |
| 三级降级 | CDN → 本地 SharedPreferences 缓存 → 编译期内置兜底 |
| 版本比较 | domains.json 的 version 递增,App 比较后才更新本地缓存 |
| 自动发布 | publish.py 调接口拉域名,自动 +1 版本并发布 |
domains.json 设计
{
"version": 4,
"updatedAt": "2026-08-16T15:20:28.319Z",
"payload": "eyJjaGFubmVscyI6eyJ4Y2hhdCI6ey..."
}payload 是 base64 编码的 JSON,解码后是多渠道结构:
{
"channels": {
"xchat": { "primary": "https://xchat-0816-hw-app-api.hbshxnn.cn", "fallbacks": [] },
"bwcj": { "primary": "https://bwcj-0816-hw-app-api.hbshxnn.cn", "fallbacks": [] },
"dypj": { "primary": "https://dypj-0816-hw-app-api.hbshxnn.cn", "fallbacks": [] },
"xsm": { "primary": "https://xsm-0816-hw-app-api.hbshxnn.cn", "fallbacks": [] },
"91mf": { "primary": "https://91mf-0816-hw-app-api.hbshxnn.cn", "fallbacks": [] }
}
}Usage (Node.js)
const domains = require('domains007');
console.log(domains.getChannel('xchat')); // { primary, fallbacks }
console.log(domains.getChannelNames()); // ["xchat", "bwcj", ...]
console.log(domains.getVersion()); // 4发布流程(一键脚本)
域名更新走接口,无需手动编辑任何文件。每次执行 publish.py 自动完成整个发布:
cd npm_plan/domains
python3 publish.py # 交互:打印摘要 → 输入 y 发布
python3 publish.py --yes # 跳过确认直接发布脚本自动完成 6 件事:
- 遍历 5 个产品调接口拉最新域名(失败的产品用旧配置兜底,其余继续)
- 所有域名都无变动 → 打印提示并退出,不发布
domains.json的version+1、package.json的versionpatch +1- 打印「每个产品新域名 + 新旧版本号」变更摘要
npm publishgit commit到本地(不 push)
域名接口
- 地址:
http://16.163.130.1:8080/api/v1/domains?product={product}&key=DOMAINS_API - 支持的产品:
xchat/bwcj/dypj/xsm/91mf - 返回
data[],第一个 domain 作 primary,其余作 fallbacks
首次使用(发布前登录一次)
当前 token 可能已失效,先登录:
npm login之后每次只需 python3 publish.py 回车 y 即可。
Android: Fetch from CDN
https://cdn.jsdelivr.net/npm/domains007/domains.json
https://cdn.jsdelivr.net/npm/domains007@latest/domains.json
https://unpkg.com/domains007@latest/domains.json进阶方向
- 签名校验:对 payload 加 HMAC 签名,App 内置公钥验签,防止 CDN 被劫持篡改
- 灰度发布:利用 npm dist-tag(
npm publish --tag beta)实现按 tag 拉不同版本
License
MIT
