Skip to main content

获取文章评论

公开接口。只返回已通过审核的评论(status = 'approved' 或旧数据缺失 status),按写入顺序(rowid ASC)返回;待审核评论对访客不可见。 响应:
响应头: Cache-Control: no-store——评论是实时互动内容,不做边缘缓存,发表 / 删除后刷新立即可见。

发表评论

公开接口,无需认证。 请求体:
成功响应(201):
写入顺序上有四道校验:来源校验 → 频率限制 → 参数与嵌套校验 → 评论数上限 → 重复内容拦截。频率限制依赖 KV 绑定 BLOG,未绑定时会静默失效并在日志里打一条 warning,建议始终绑定。
错误响应: 前端 saveComment 会把后端 error 文案透传到表单状态行,用户可直接看到失败原因(不再只显示 HTTP 状态码)。

删除单条评论(文章维度)

需会话 token。评论不存在返回 404「评论不存在」,成功返回 { "ok": true }。

全局评论列表(管理)

查询参数: status(approved / pending,留空或 all 返回全部) 按 rowid DESC 返回,每条评论附带 post_title 字段(LEFT JOIN posts),方便管理后台展示所属文章。

审核 / 删除(管理)

都需要会话 token。status 只接受 approved / pending,其余值返回 400「status 只能是 approved 或 pending」;评论不存在返回 404「评论不存在」。

排序切换反馈

前台可在「最热 / 最新」间切换:点击即刻高亮反馈并显示骨架占位过渡,列表连贯不跳动,不会出现先空白 / 先「无数据」再出内容的情况。后台同样可一键切换精选与置顶。

嵌套回复

评论通过 parent_id 支持最多 3 层嵌套(顶层评论 + 两层回复)。超过 3 层的提交会被服务端以 400「最多支持 3 层嵌套回复」拒绝;前台的「回复」按钮在第 3 层不再出现。
父评论不存在(或已被删除)时,该评论会作为顶层评论展示,不会丢失。

重复发送拦截

同一分区(文章 / 留言板,分区即 post_id)下,相同昵称 + 相同内容只允许出现一次:
  • 命中重复返回 409「请勿重复发送相同内容」,前端透传该提示
  • 覆盖「误触双击」与「脚本刷同一段文字」两类场景
  • 不同分区互不影响(gb-note 与某篇文章各自独立判定),且判定按 post_id 隔离

安全机制

长度与数量上限

评论审核开关

审核由站点设置键 moderate_comments 控制(见站点设置),存在 D1 site_settings 表:
判定是 严格等值比较:只有存进去的值恰好是字符串 "1" 才开启审核,"true" / "on" 等都不会生效。

列表排序与分页

评论列表改为服务端分页:每页 8 条顶层评论,每条顶层评论携带自己的回复;支持 sort=hot / sort=new(最热 / 最新)。前端「加载更多」继续取下一页,留言板复用同一套管道。

评论互动

评论支持点赞、精选与置顶:
  • 前台:POST /api/comments/:id/like,同一 IP 对同一条评论去重
  • 后台:一键切换精选 / 置顶,列表按置顶、精选、时间排序
  • 删除文章时评论互动字段随评论级联清理

评论反机器人

敏感词与批量操作

  • COMMENT_BLOCKLIST 环境变量与 site_settings.comment_blocklist 共同组成敏感词库;命中昵称或正文直接拒绝
  • 后台评论列表支持多选(含全选本页),一次请求完成批量通过 / 转待审 / 批量删除,并写入操作审计