Open Kounter 是一个基于 EdgeOne Pages Functions 和 Blob 存储的无服务器计数器服务,旨在替代 LeanCloud 为静态网站(如 Hexo)提供 PV/UV 统计功能。它包含一个完整的管理后台,支持数据管理、导入导出、域名白名单、旧版 KV 一键迁移、Passkey 无密码登录和 OIDC 单点登录。

更详细的介绍和部署指南请参考:
你可以通过 EdgeOne Pages 一键部署或手动配置构建:
一键部署:
注意:点击上方按钮前,建议先 Fork 本仓库,并在跳转后的页面中确认仓库地址为你 Fork 后的地址。
手动部署配置:
edgeone.json)npm run builddist22更多 EdgeOne Pages文档:https://pages.edgeone.ai/zh/document/product-introduction
Open Kounter 早期使用 EdgeOne Pages KV 保存计数器、配置和认证信息,但 KV 的全球同步是最终一致模型,在多节点场景下会有明显同步延迟。
现在主存储已经切换为 Blob,并在核心读取路径中使用强一致读取。这样做的目标很明确:解决 KV 全球同步存在延迟的问题,让计数、配置和认证状态在写入后能更快、更稳定地读到最新值。
本项目使用 Blob 作为主存储,部署后会在 cloud-functions 中自动创建并使用名为 open-kounter 的 Blob Store。
open-kounter 作为 Blob Store 名称OPEN_KOUNTER_BLOB_STOREOrigin 的 hostname 作为 RP IDPASSKEY_RP_IDPASSKEY_RP_NAMEOIDC_ISSUER:OIDC 提供商的 Issuer URL(如 https://auth.example.com/realms/master)OIDC_CLIENT_ID:客户端 IDOIDC_CLIENT_SECRET:客户端密钥OIDC_REDIRECT_URI:回调地址(如 https://your-domain.com/api/oidc/callback)如果你是从旧版 KV 存储迁移,请额外绑定旧 KV 命名空间,变量名仍为:OPEN_KOUNTER。
部署并配置完成后,访问你的项目网址,首次访问将引导你设置管理员 Token。
.
├── client/
│ └── adapter.js # 客户端适配器,模拟 LeanCloud 行为
├── cloud-functions/ # 主后端逻辑 (Blob API)
│ └── api/
│ ├── auth.js # 认证逻辑
│ ├── counter.js # 核心计数器逻辑
│ ├── init.js # 初始化与迁移接口
│ ├── passkey.js # Passkey 相关逻辑
│ └── oidc/ # OIDC 单点登录
│ ├── login.js # OIDC 登录发起
│ ├── callback.js # OIDC 回调处理
│ └── status.js # OIDC 绑定状态查询
├── edge-functions/ # 兼容旧版 KV 的迁移出口
│ └── legacy-api/
│ └── migrate.js # 导出旧 KV 数据供 Blob 导入
├── src/ # 前端管理后台 (Vue 3 + Vite)
│ ├── components/
│ │ ├── dashboard/
│ │ │ ├── CounterList.vue # 计数器列表
│ │ │ ├── DataBackup.vue # 数据备份与恢复
│ │ │ ├── DomainConfig.vue # 域名白名单配置
│ │ │ ├── OidcManager.vue # OIDC 绑定管理
│ │ │ ├── PasskeyManager.vue # Passkey 管理
│ │ │ ├── SingleCounterManager.vue # 单个计数器管理
│ │ │ └── TotalStats.vue # 统计概览
│ │ ├── Dashboard.vue # 仪表盘主组件
│ │ └── Login.vue # 登录组件
│ ├── utils/ # 工具函数
│ ├── App.vue # 主应用组件
│ ├── main.js # 入口文件
│ └── style.css # 全局样式
├── edgeone.json # EdgeOne 配置文件
├── index.html # HTML 入口
├── package.json # 项目依赖
├── tailwind.config.js # Tailwind 配置
└── vite.config.js # Vite 配置
所有 API 的基础路径为 /api。
GET /api/countertarget (必填,计数器的 Key,如 site-pv){
"code": 0,
"data": {
"time": 100,
"target": "site-pv",
"created_at": 1700000000000,
"updated_at": 1700000000000
}
}
POST /api/counter{
"action": "inc",
"target": "site-pv"
}
POST /api/counter{
"action": "batch_inc",
"requests": [
{ "target": "site-pv" },
{ "target": "/posts/hello-world/" }
]
}
需要在 Header 中携带 Authorization: Bearer <YOUR_TOKEN>。
POST /api/counter{
"action": "set",
"target": "site-pv",
"value": 1000
}
POST /api/counter{
"action": "delete",
"target": "site-pv"
}
POST /api/counter{
"action": "list",
"page": 1,
"pageSize": 20
}
POST /api/counter{ "action": "export_all" }POST /api/counter{
"action": "import_all",
"data": { ... } // 导出的 JSON 数据
}
POST /api/counter{
"action": "set_config",
"allowedDomains": ["example.com", "*.example.com"]
}
| 变量名 | 必需 | 说明 |
|---|---|---|
OPEN_KOUNTER_BLOB_STORE | 否 | 自定义 Blob Store 名称,默认 open-kounter |
ADMIN_TOKEN | 否 | 预设管理员 Token(优先级高于 Blob 中存储的 Token) |
PASSKEY_RP_ID | 否 | Passkey RP ID,默认使用当前域名 |
PASSKEY_RP_NAME | 否 | Passkey 显示名称,默认 Open Kounter |
OIDC_ISSUER | 否 | OIDC Issuer URL |
OIDC_CLIENT_ID | 否 | OIDC 客户端 ID |
OIDC_CLIENT_SECRET | 否 | OIDC 客户端密钥 |
OIDC_REDIRECT_URI | 否 | OIDC 回调地址 |
Open Kounter 支持三种登录方式,登录页会自动检测可用的登录方式并渐进式展示:
登录页加载时会先进行环境检测(显示加载动画),检测完成后仅展示已配置/已绑定的登录方式,保持界面简洁。
本项目基于 MIT License 开源。