星河避难所

返回

自动化我的友链申请脚本:让孤岛互相连起来Blur image

友链这东西,说出来有点浪漫。

2025 年了,个人博客基本没有什么流量,更多像是一座座散落在海上的小岛。
偶尔有海风吹过,但大多数时候,就是悄悄发光、自娱自乐。

而友链……就像是在这些小岛之间铺上一条条细细的桥。
你看不到桥的尽头,但知道那里至少还有一个同样孤独、同样固执的人。


为什么拖了这么久才开放友链申请?#

刚写博客那阵子,我其实没太敢申请友链。不是因为不想被发现,而是因为我真的是那种比较内向的类型。

内容少也不自信,总觉得“我这样去申请友链,会不会显得很冒失?”
再加上每个人对友链的理解都不太一样:

  • 有人只收特定领域的高质量博客
  • 有人觉得必须线下认识
  • 也有人坚持要有一定的线上互动次数

即便对方没有列要求,我心里还是会嘀咕:“我们不熟,贸然提出会不会不太礼貌?”

传统的友链申请方式大多是:留言、邮件,或在 GitHub 提 issue。看似简单,但对我这种“有自助收银台绝不走人工”的 I 人来说,其实是需要一点点勇气的。

直到有一次,我在看一位老师的博客时,看到有人问:“这么多友链,你是怎么维护的?”
老师回: “脚本。”

那一瞬间我有点被点醒了:
既然我不好意思主动打招呼,那是不是可以先让别人跟我打招呼不要那么困难?


说干就干:自动化友链要处理些什么?#

为了做到“自动添加”,其实需要处理的事情很简单:

  1. 对方网站必须能访问
  2. 不能让广告站点钻空子
  3. 对方真得挂上了我的友链

于是我要求申请方提供友链页地址,然后脚本负责验证:

  • 确认主站是正常可访问的
  • 主站域名与友链页域名一致(避免广告跳转)
  • 友链页中确实存在我的网站

通过就添加,没通过就直接拒绝,简单粗暴但有效。


技术实现:我是怎么做的?#

1. 友链数据剥离成 JSON(重点)#

一开始我的友链是写在 Astro 的页面里的。
但这意味着:

改一个字 → 就得重新打包部署

非常麻烦。

后来改用 SSR(服务端渲染) 后,我意识到:

完全没必要把友链打包进页面里。
数据完全可以在服务端“即时读取”。

于是我把友链抽成一个 links.json 文件,并且 不再使用 import 引入它
因为一旦 import,它就会在构建时被写死。

正确的方式是:

const raw = await fs.readFile(linksPath, 'utf-8')
const { friends } = JSON.parse(raw)
ts

这样:

  • JSON 是独立的数据源
  • SSR 每次渲染页面都会读取到最新内容
  • 修改 JSON = 友链立即生效
  • 无需重新打包

这也是我把友链从页面剥离出来的根本原因。


2. 头像检查 + 上传 OSS#

用户提交的头像链接永远无法保证靠谱:

  • 有的不是图片
  • 有的没 content-type
  • 有的会失效

我的解决方案是:

  • 先判断扩展名是否是图片
  • 再通过请求检查 content-type
  • 最后统一上传到 OSS

我用的是 ossutil

因为它是 CLI,不需要把 AccessKey 写进代码里,对我这种 Node 不熟练的人来说更安全。

(当然也可以不用 OSS,不过不管是速度还是稳定性都不如 OSS 省心)


3. 检查对方是否挂了我的链接#

为了避免“我挂你,你不挂我”或者广告的情况出现,脚本会:

  1. 访问对方主站
  2. 检查友链页是否同域
  3. 抓取页面,看是否包含我的链接

确认通过,才会添加。


4. 自动更新 JSON + 顺手 Git 提交#

友链通过验证后,脚本会:

  • 把条目写入 links.json
  • 自动执行 git add → commit → push

因为是 SSR,页面下一次请求时就会看到最新的友链数据。

不需要重新打包,也不需要重新部署。

整个流程非常轻量。


SSR 这个环节的重要性#

在写脚本之前,我也想过纯静态博客能不能实现自动化友链。
答案是:能,但非常折腾,不值得。

纯静态的问题:

  • 页面打包后就是死的,无法在服务端执行校验逻辑
  • 用户无法直接让服务器写入文件
  • 想走 GitHub Actions,需要用户先有权限 push(显然不行)

虽然理论上可以:

  • 表单提交 → 云函数写文件 → 云函数 push GitHub → Actions 构建 → 部署

但整个链路太长太容易出问题。

相比之下:

SSR:写一个 API 就全部搞定#

Cloudflare、Vercel 都能跑 SSR
甚至没服务器也能跑

所以最后我还是选择了最干净、最好理解、扩展性最高的方案:
在 SSR 里加一个接口,让它帮我跑脚本、改 JSON、推 Git 就完事了。


最后的一点小感慨#

整个自动化流程,说白了,就是给像我这样的 I 人一点点缓冲空间。

我非常尊重那些坚持手工审核友链的朋友

那是对自己博客节奏和边界的坚持,我完全理解。

但我也知道,有不少朋友可能跟我一样:

  • 觉得对方的博客不错
  • 想互相交换友链
  • 却迟迟按不下那个“开口”的按钮

这个脚本解决不了我鼓起勇气去申请别人友链的问题。

但至少 如果你也是这样的 I 人,来我的博客交换友链时,你完全可以毫无心理负担

如果你想看完整的代码与改动,可以看这里:
👉 点击查看

自动化我的友链申请脚本:让孤岛互相连起来
https://hejunjie.life/blog/kdir85h1
作者 何俊杰
发布时间 2025年11月14日
版权信息 CC BY-NC-SA 4.0
评论似乎卡住了,尝试刷新?✨