个人博客最难长期维护的功能之一,往往不是文章系统本身,而是评论区。

文章可以用静态站点生成器发布,图片可以托管到对象存储,页面可以放到 CDN 上。但一旦需要评论,就会遇到一连串现实问题:用户怎么登录?评论数据放在哪里?图片怎么上传?跨域怎么处理?会不会为了一个评论区而维护一整套后端服务?

ZiKiBoard 想解决的就是这个问题:为博客提供一套轻量、可嵌入、边缘原生的评论系统,让评论区像引入一段脚本一样接入,同时又能保留自托管项目对数据、身份和部署方式的掌控。

项目地址:https://github.com/zack-zzq/ZiKiBoard

它是什么

ZiKiBoard 是一个运行在 Cloudflare Workers 上的博客评论系统。它把评论 API、登录回调、图片访问和前端小组件都放在同一个 Worker 体系里,通过 Cloudflare 的几类基础设施组合完成完整能力:

  • Workers 负责 API 路由、鉴权、评论读写和静态资源分发。
  • D1 保存用户、第三方登录账号、会话、评论、回复、表情反应和上传记录。
  • R2 保存评论中上传的图片。
  • KV 缓存 OAuth/OIDC 登录状态和 OIDC discovery 文档。
  • Worker static assets 提供可嵌入的前端脚本和样式。

这意味着 ZiKiBoard 不需要额外维护一台传统服务器。对个人博客或小型内容站来说,这个取舍很实际:评论区需要动态能力,但没有必要因此把整个博客从静态部署拉回到传统后端架构。

为什么选择边缘架构

评论系统有一个很典型的访问模式:读多写少、用户分布不固定、页面里只占一小块,但又必须足够快。把评论 API 和小组件放到 Cloudflare Workers 上,天然适合这种场景。

读者打开文章时,页面只需要加载 embed.jsstyles.css,评论列表通过当前文章的 data-blog-id 拉取。每篇文章的评论线程被 blog id 隔离,同一个评论系统可以服务多个页面,而不需要为每篇文章单独配置。

接入方式也保持克制:

<link rel="stylesheet" href="https://comments.example.com/styles.css" />
<div id="zikiboard" data-blog-id="blog/post-slug"></div>
<script src="https://comments.example.com/embed.js"></script>

这三行代码背后对应的不是一个简单留言板,而是一套完整的评论体验:登录、发表评论、嵌套回复、Markdown 内容、图片上传、@ 提及和表情反应。

登录:面向真实使用场景

一个评论系统是否好用,登录体验很关键。ZiKiBoard 支持 OpenID Connect,也支持 GitHub OAuth 2.0。默认配置可以覆盖 Google、Microsoft、GitHub 等常见身份源,也可以接入任何提供 discovery document 的 OIDC issuer。

项目里把认证提供方配置放在 config/auth-providers.json,但不把真实密钥写进仓库。配置文件只保存 provider 元数据和环境变量名称,真正的 client id、client secret 通过 Cloudflare vars 或 secrets 注入。

这个设计有两个好处:

  • 本地和生产环境可以共用同一套 provider 描述。
  • 仓库里不会出现真实 OAuth 密钥,部署时再把敏感信息交给 Cloudflare 管理。

登录流程中,ZiKiBoard 使用 KV 保存短期 auth state,OIDC 登录会使用 PKCE、nonce 和 JWK 校验;登录成功后,会把用户身份与 provider subject 绑定到 D1。会话 cookie 对应的 session token 不直接落库,而是以哈希后的 session id 存储,降低明文令牌泄露风险。

评论体验:小组件也可以很完整

ZiKiBoard 的前端不是简单地提交一段文本。它提供了一个嵌入式评论编辑器,包含写作和预览模式,并支持常用 Markdown 子集,例如粗体、斜体、链接、行内代码、引用和列表。

对于博客评论来说,图片经常是刚需。ZiKiBoard 支持把图片上传到 R2,并在评论内容里以 Markdown 图片语法插入。服务端会限制文件类型和大小,当前配置支持 JPEG、PNG、GIF、WebP,默认最大 5MB。上传后的图片通过 /media/... 路由访问,并带有适合静态资源的缓存头。

在互动层面,它支持:

  • 按文章隔离的评论列表。
  • 嵌套回复。
  • @ 提及建议。
  • 表情反应。
  • 评论编辑和删除。
  • 删除后的评论脱敏展示。

这些功能让它更接近一个“博客讨论区”,而不是一次性留言表单。

数据模型:简单,但边界清楚

ZiKiBoard 的第一版数据模型保持得比较直接。D1 里主要有几类表:

  • users:评论用户的基础资料。
  • auth_accounts:第三方登录账号与本地用户的绑定关系。
  • sessions:登录会话。
  • comments:评论、回复、Markdown 内容、提及和图片 URL。
  • comment_reactions:用户对评论的表情反应。
  • uploads:图片上传记录和 R2 key。

这样的拆分让评论、身份、会话和上传记录各自独立,后续如果要增加审核、通知、管理后台或反垃圾策略,也有比较清晰的扩展位置。

适合谁使用

ZiKiBoard 适合那些已经有博客或静态站点,但不想把评论交给第三方托管平台的人。

如果你希望:

  • 评论数据保存在自己的 Cloudflare 资源里;
  • 站点只通过几行 HTML 接入评论区;
  • 不为了评论功能维护一台后端服务器;
  • 支持 GitHub、Google、Microsoft 或自定义 OIDC 登录;
  • 评论体验不仅限于纯文本留言;

那么 ZiKiBoard 就是一个很合适的起点。

它不是一个庞大的社区系统,也不试图替代论坛、工单或社交平台。它的目标更明确:把个人博客最需要的评论能力做完整,并用 Cloudflare 的边缘基础设施把维护成本压低。

本地开发和部署

本地启动流程保持在常见的 Workers 项目习惯内:

npm install
Copy-Item .dev.vars.example .dev.vars
npm run types
npm run db:migrate:local
npm run dev

生产环境需要提前创建 Cloudflare D1、KV 和 R2 资源,并把 wrangler.jsonc 里的绑定替换成自己的资源信息:

npx wrangler d1 create zikiboard-db
npx wrangler kv namespace create AUTH_CACHE
npx wrangler r2 bucket create zikiboard-images
npm run db:migrate:remote
npm run deploy

当评论服务和博客部署在不同域名时,还需要配置 CORS_ORIGINS。如果跨站使用 cookie,则应在 HTTPS 下设置合适的 COOKIE_SAME_SITE 策略。

接下来可以继续打磨的方向

ZiKiBoard 当前已经具备博客评论系统的核心闭环。后续更值得投入的方向,可能会集中在运营和治理能力上:

  • 评论审核与管理后台。
  • 垃圾评论防护。
  • 邮件或站内通知。
  • 主题样式定制。
  • 多语言界面。
  • 更细粒度的权限和黑名单策略。

这些能力不一定要在第一版全部做完。对一个个人博客评论系统来说,先把“能稳定登录、评论、回复、上传图片、按文章隔离数据”做好,比堆很多复杂功能更重要。

结语

ZiKiBoard 的价值不只是“做了一个评论框”,而是把博客评论区重新拆成了几个适合边缘平台承载的部分:身份交给 OAuth/OIDC,结构化数据交给 D1,图片交给 R2,临时状态交给 KV,前端体验用一个可嵌入的小组件交付。

这样的组合让评论系统既轻,又完整。它保留了自托管项目的可控性,也避免了传统后端服务带来的维护负担。

如果你的博客已经在静态化、CDN 和边缘部署的路线上,ZiKiBoard 提供了一个很自然的下一步:让评论区也跟上同样的架构。


Related Posts

skillmux:把 AI Agent 的 Skill 管理变成一条命令

skillmux是面向AI Agent的Skill管理命令行工具,可统一完成多源Skill的检索、安装、升级等操作,支持一键适配多Agent运行环境,兼具元数据维护、自动化输出、安全校验能力,大幅降低Skill手动管理成本。

在 Windows 上部署 OpenShamrock 的一种方案

本文介绍在 Windows 上通过 MUMU 模拟器部署 OpenShamrock 的方法,用于搭建 QQ 机器人。包括前置条件、文件下载、模拟器配置、Magisk 和 LSPosed 安装,以及 OpenShamrock 和 QQ 的部署步骤。