零第三方依赖的评论系统:JSON 存储 + 一层回复
个人博客的评论量通常很小,接第三方服务(要求登录、带跟踪脚本、随时可能关停)性价比不高。这里用最朴素的方式:一个 JSON 文件 + 两个接口。
数据结构#
[
{
"id": "0f3a…",
"slug": "nextjs-blog-quickstart",
"name": "小林",
"content": "目录高亮这块很有用,已抄走。",
"createdAt": "2026-10-08T02:11:00.000Z",
"replyTo": null
}
]只支持一层回复:子评论通过 replyTo 指向父评论 id,不再嵌套,避免前端渲染和无障碍复杂度失控。
两个接口#
// GET /api/comments?slug=xxx
export async function GET(request: NextRequest) {
const slug = request.nextUrl.searchParams.get('slug') ?? undefined;
return NextResponse.json({ comments: readComments(slug) });
}
// POST /api/comments
const comment = addComment({ slug, name: name || '访客', content, replyTo });必须处理的三件事#
- 限流:同一 IP 20 秒内只能发一条,挡住最粗暴的刷屏。
- 长度与昵称裁剪:内容 2000 字、昵称 40 字,超长直接截断而不是报错。
- 写文件失败要降级:
catch后返回可读的错误信息,而不是 500 白屏。
const now = Date.now();
if (now - (lastPost.get(key) ?? 0) < 20_000) {
return NextResponse.json({ error: '发言太快了,请 20 秒后再试' }, { status: 429 });
}
lastPost.set(key, now);什么时候该换数据库#
- 评论需要分页、点赞、审核队列;
- 部署在多实例(文件不共享);
- 需要全文检索评论内容。
到那个时候,把 lib/comments.ts 的三个函数换成 SQL 实现即可,页面和接口一行都不用改——这就是把存储收敛到一个文件的价值。
部署提醒:Serverless 平台的文件系统通常是只读或临时的,评论要持久化就得挂载卷,或者此时再换数据库。
付费下载 · ¥29.00
付款后立即开通下载链接(30 天有效、可下载 5 次)。在微信中打开本页可直接支付,在电脑上则显示扫码支付。
微信扫码加客服
评论
正在加载评论…