国庆节10月1日
--


记录如何使用 hexo-circle-of-friends 项目为 Astro 博客搭建朋友圈功能,包括部署、踩坑和最终效果。

博客已经有了友链页面,但只能看到朋友们的博客链接,不能看到他们最近发了什么文章。于是想找一个「朋友圈」功能,能自动抓取好友的最新文章并展示。
经过调研,发现了 hexo-circle-of-friends 这个项目。虽然名字里有 “hexo”,但它实际上是一个独立的后端服务,不依赖 Hexo,任何博客框架都能用。
hexo-circle-of-friends 的核心功能:
首先 Fork 项目到自己的 GitHub 仓库:
1https://github.com/tianshihao2003/hexo-circle-of-friends这是核心配置文件,主要修改:
1# 友链页地址 - 填写你的友链页面2LINK: [3 { link: "https://blog.tsh520.cn/friends/", theme: "firefly" },4]5
6# 极简模式 - 输出静态 JSON,无需后端7SIMPLE_MODE: true8
9# 存储方式10DATABASE: "sqlite"11
12# 部署方式13DEPLOY_TYPE: "github"14
15# 每个好友最多获取几篇文章16MAX_POSTS_NUM: 517
18# 定时任务 - 每天 5 次19CRON: "0 0,6,12,18,21 * * *"因为我的博客是 Astro + 自定义主题,不在内置支持列表中,需要在 css_rules.yaml 中添加自定义规则:
1link_page_rules:2 {3 # ... 已有主题 ...4 firefly:5 {6 author: [{ selector: ".friend-card-name", attr: "text" }],7 link: [{ selector: ".friend-card-link", attr: "href" }],8 avatar: [{ selector: ".friend-card-avatar__img", attr: "data-src" }],9 },10 }关键点:头像用的是 data-src 而不是 src,因为我的友链卡片用了懒加载。
下载预编译二进制到项目目录,运行爬虫测试:
1.\fcircle_core.exe看到以下输出说明配置成功:
1成功友链数 14,失败友链数 62本次获取总文章数 70我选择了 EdgeOne Pages 来托管生成的 data.json。
踩坑记录:CORS 跨域问题
部署后发现浏览器无法从 blog.tsh520.cn 请求 cir.tsh520.cn/data.json,控制台报错:
1Access to fetch at 'https://cir.tsh520.cn/data.json' from origin 'http://localhost:4321'2has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present解决方案:使用 edgeone.json 配置 CORS
EdgeOne Pages 不支持 _headers 文件(那是 Cloudflare Pages 的规范),需要使用 edgeone.json:
1{2 "headers": [3 {4 "source": "/*",5 "headers": [6 {7 "key": "Access-Control-Allow-Origin",8 "value": "*"9 },10 {11 "key": "Access-Control-Allow-Methods",12 "value": "GET, POST, PUT, DELETE, OPTIONS"13 },14 {15 "key": "Access-Control-Allow-Headers",16 "value": "Content-Type, Authorization"17 }18 ]19 }20 ]21}data.json 的结构:
1{2 "statistical_data": {3 "friends_num": 20,4 "active_num": 14,5 "error_num": 6,6 "article_num": 70,7 "last_updated_time": "2026-07-13 10:19:17"8 },9 "article_data": [10 {11 "floor": 1,12 "title": "文章标题",13 "created": "2026-07-13",14 "updated": "2026-07-13",15 "link": "https://example.com/post/1",16 "author": "作者名",17 "avatar": "https://example.com/avatar.jpg"18 }19 ]20}创建 src/config/circleConfig.ts:
1export const circleConfig: CircleConfig = {2 dataUrl: "https://cir.tsh520.cn/data.json",3 pageSize: 20,4 showStats: true,5 showFloor: false,6 cacheTime: 5 * 60 * 1000, // 5 分钟缓存7};1┌─────────────────────────────────────────────┐2│ 🎣 钓鱼 🔄 全部友链 > │ ← 顶部导航栏3├─────────────────────────────────────────────┤4│ 📢 来自友链 xxx 的文章: xxx │ ← 随机动态通知5├─────────────────────────────────────────────┤6│ 🌊 鱼塘 好友 20 · 活跃 14 · 动态 70 │ ← 统计区域7├─────────────────────────────────────────────┤8│ ┌─────┐ ┌─────┐ ┌─────┐ ┌─────┐ │9│ │卡片1│ │卡片2│ │卡片3│ │卡片4│ │10│ └─────┘ └─────┘ └─────┘ └─────┘ │11│ ... ∞ │ ← 无限滚动12└─────────────────────────────────────────────┘每个文章卡片包含:
1error: linker `link.exe` not found原因:Windows 上需要安装 Visual Studio Build Tools。
解决:下载预编译二进制代替本地构建。
原因:blog.tsh520.cn 和 cir.tsh520.cn 是不同源。
解决:在 EdgeOne 配置 edgeone.json 添加 CORS 响应头。
原因:Astro 的 <style> 默认是 scoped 的,JavaScript 动态创建的元素没有 scoped 属性。
解决:将样式提取到独立的 CSS 文件并 import:
1---2import "@/styles/features/circle.css";3---原因:Swup 客户端导航时,DOMContentLoaded 不会再次触发。
解决:使用 astro:page-load 事件,并在 astro:before-swap 中重置初始化标记。
在 src/content/friends/ 目录下创建 Markdown 文件:
1---2title: 好友博客名3imgurl: https://example.com/avatar.jpg4desc: "博客描述"5siteurl: https://example.com6tags: [Blog]7weight: 108enabled: true9---GitHub Actions 会按照 CRON 配置自动运行(每天 0/6/12/18/21 点),也可以在 Actions 页面手动触发。
部署完成后访问 /circle/ 页面即可。
hexo-circle-of-friends 是一个非常实用的项目,虽然名字里有 “hexo”,但完全框架无关。通过 Simple Mode + EdgeOne 的方案,我实现了一个零后端、纯静态的朋友圈功能。
主要收获:
如果你也想给博客加一个朋友圈功能,不妨试试这个方案。
暂未播放



"人生最重要的两天,一是你来到世界的那天,二是你明白为什么来到这个世界的那天。"—— 马克·吐温


