把博客评论留在自己的服务器上
静态站点没有后端也能有真评论:一个零依赖Node服务、一个JSON文件、一份前端组件,数据完全自己掌握。
静态博客加评论,通常有两个极端:接第三方服务要注册账号、要加载外部脚本、数据不在自己手里;自己搭一套完整后端又太重。其实中间还有一条很窄但够用的路。
需求先砍到最小
个人博客的评论只需要四件事:按文章取列表、提交一条、不被人灌爆、数据能自己导出。至于登录、点赞、无限嵌套、邮件通知,都不是刚需。
于是后端可以只是两个接口:
GET /api/comments?slug=xxx
POST /api/comments
数据存一个JSON文件,进程内用队列串行化写入,写临时文件再原子rename。这个量级下,文件存储比引数据库更省事,备份就是拷一个文件。
服务同时托管静态产物
既然已经有一个Node进程,让它顺带把dist/目录发出去,页面和API同源,CORS、混合内容、额外域名全都省了。
const server = http.createServer((req, res) => {
const url = new URL(req.url, `http://${req.headers.host}`);
if (url.pathname.startsWith('/api/')) return handleApi(req, res, url);
return serveStatic(req, res, url);
});
静态部分只需处理三件事:路径穿越校验、目录补index.html、按文件类型给缓存头。HTML短缓存、带哈希的构建资源长缓存即可,压缩交给前置Nginx。
必须挡在服务端的事
前端做校验只是体验,后端才是边界:
- 限制请求体大小,超过直接断开;
- 昵称、内容长度设上限,去掉控制字符;
- 蜜罐字段:表单里放一个对真人隐藏的输入,机器人填了就静默丢弃;
- 按IP做简单时间窗限流,例如60秒最多3条;
- 邮箱只存不回传,列表接口里剔除隐私字段;
- 评论内容一律当纯文本存,前端用
textContent渲染,绝不拼innerHTML。
最后一条是XSS的关键。评论属于典型的不可信输入,任何”支持一下Markdown”的想法,都要先想清楚转义链路。
前端做成可插拔
把评论组件和后端解耦,配置里给三种模式:
| 模式 | 适用场景 |
|---|---|
self-hosted | 有自己的服务器,同源部署 |
local | 只上传静态文件,留言存在浏览器本地,用于演示 |
waline | 想用现成托管评论服务 |
接口失败时给明确提示而不是静默空白,这样部署方式变了也能快速定位。
这套东西的价值不在功能多,而在于没有外部依赖:不注册第三方账号、不加载境外CDN、不担心服务关停,删库就是删一个JSON文件。对已备案的个人站点来说,这点尤其省心。
评论 0
评论保存在本站服务器,无需登录。带「作者」标识的是站主回复,请友善交流。
还没有评论,来写第一条。