:: 技术 0xBC // 技术分享
Typecho × Astro:把博客改成无头 CMS 架构的完整实践
把用了多年的 Typecho 保留为后台内容管理,前端换成 Astro 静态渲染——这就是本站现在的架构。这篇文章记录完整的改造思路与踩坑。
#为什么要「无头」
传统的 Typecho 主题由 PHP 直接渲染,存在几个痛点:
- 页面性能受制于服务器与 PHP 执行速度
- 前端工程化(组件化、按需构建、Tree Shaking)无从谈起
- 难以复用同一份内容做小程序、App 等多端输出
无头(Headless)方案把内容与展示彻底分离:
Typecho 负责内容存储与管理后台,Astro 负责高性能展示层,两者通过 API 通信。
#整体架构
text┌─────────────┐ RESTful API ┌──────────────┐
│ Typecho │ ───────────────▶ │ Astro │
│ (内容管理) │ getarticle … │ (静态构建) │
└─────────────┘ └──────────────┘
▲ │
│ 评论提交(令牌代理) │
└──────────────────────────────────┘构建期,Astro 通过分页接口拉取全部文章并预渲染为静态页面;运行期,评论列表与搜索通过轻量 API 路由实时转发,保证「新内容即时可见」。
#关键实现
#评论的令牌代理
Typecho 从 1.2 起给评论表单加了反垃圾令牌:_ = md5(secret + '&' + 页面URL)。无头站点的服务端代理按下面三步处理:
- 抓取文章页 HTML,还原内嵌令牌
- 以该页面 URL 作为
Referer - 转发评论字段到原生
/comment端点
#性能对比
同一篇文章在两种架构下的表现(实测本站):
| 指标 | PHP 直渲染 | Astro 静态 |
|---|---|---|
| 首屏 TTFB | ~180ms | ~12ms |
| LCP | 1.9s | 0.4s |
| 并发能力 | 受 PHP-FPM 限制 | CDN 级别 |
#踩坑记录
- 插件返回的
text是 原始 Markdown,带<!--markdown-->前缀,需要前端自行渲染 - 评论令牌绑定的是「抓取时的 URL」,Referer 必须与之一致
- 中文分类会自动生成中文 slug,URL 里记得做
encodeURIComponent
bash# 检查 API 是否正常
curl -s "https://example.com/index.php/api?token=***&method=getbloginfo" | jq总结:无头改造后,写作流程没有变化,但前端获得了现代工程化的一切。值得折腾。
本文链接:/post/typecho-astro-headless/ · 转载请注明出处 · 原文由 Typecho 驱动
访客甲 #4
架构思路很清晰,正好在考虑把老博客做无头改造,收藏了!
博主 #5
欢迎交流,评论区就是用文中提到的令牌代理方案实现的。
频率测试A #6
频率测试第一条 1791382170817
频率测试A #7
频率测试第一条 1791382312763
频率测试A #8
频率测试第一条 1791382410051
频率测试A #9
频率测试第一条 1791382422689
频率测试A #10
频率测试第一条 1791382435237
频率测试B #11
频率测试第二条(间隔<60s)
隔壁老王 #12
已订阅 RSS,希望多更~
半亩方塘 #14
哈哈,跟我理解的一样,放心用了。
FastPHP #13
写得很清楚,收藏了,回头照着实践一遍。
半亩方塘 #15
mark 一下,周末有空细读。
沈青崖 #16
插个楼:实测下来数据量大了之后要注意缓存。
数字游民 #18
哈哈,跟我理解的一样,放心用了。
FastPHP #21
楼上 +1,我也想知道。
半亩方塘 #22
插个楼:实测下来数据量大了之后要注意缓存。
猫爪敲键盘 #33
感谢解答,疑问解决了!
猫爪敲键盘 #45
作者回复得真快,体验好评。
隔壁老王 #64
这个问题我踩过,翻我博客有篇笔记专门讲这个。
隔壁老王 #24
这么一看确实是版本差异导致的,结案。
FastPHP #17
这个问题我踩过,翻我博客有篇笔记专门讲这个。
CC #19
感谢解答,疑问解决了!
CC #32
补充一点:官方文档里其实有提到这个边界情况。
夜航星 #20
插个楼:实测下来数据量大了之后要注意缓存。
夜航星 #25
感谢解答,疑问解决了!
FastPHP #30
插个楼:实测下来数据量大了之后要注意缓存。
FastPHP #58
作者回复得真快,体验好评。