惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
人人都是产品经理
人人都是产品经理
Cisco Talos Blog
Cisco Talos Blog
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
V
V2EX
博客园 - 三生石上(FineUI控件)
Martin Fowler
Martin Fowler
WordPress大学
WordPress大学
D
Docker
S
SegmentFault 最新的问题
博客园 - 聂微东
美团技术团队
Apple Machine Learning Research
Apple Machine Learning Research
月光博客
月光博客
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
Last Week in AI
Last Week in AI
M
MIT News - Artificial intelligence
F
Fortinet All Blogs
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
The GitHub Blog
The GitHub Blog
GbyAI
GbyAI
L
LangChain Blog
Vercel News
Vercel News
博客园 - 叶小钗
MongoDB | Blog
MongoDB | Blog
Stack Overflow Blog
Stack Overflow Blog
H
Help Net Security
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
The Cloudflare Blog
Engineering at Meta
Engineering at Meta
T
Threat Research - Cisco Blogs
T
Threatpost
Scott Helme
Scott Helme
T
Tailwind CSS Blog
Latest news
Latest news
Stack Overflow Blog
Stack Overflow Blog
Blog — PlanetScale
Blog — PlanetScale
The Register - Security
The Register - Security
罗磊的独立博客
P
Proofpoint News Feed
腾讯CDC
S
Schneier on Security
雷峰网
雷峰网
A
About on SuperTechFans
T
Tenable Blog
F
Full Disclosure
Cyberwarzone
Cyberwarzone
博客园_首页
有赞技术团队
有赞技术团队
K
Kaspersky official blog

文章列表

Astro框架Fuwari主题侧边栏添加Umami访问统计 免费领取网易云音乐7天会员 小米MiMo Token Plan免费送辣! Astro框架Fuwari主题实现仿hexo-abbrlink功能 观《鬼灭之刃:无限城篇 第一章 猗窝座再袭》首映有感
为Fuwari框架适配友链状态显示
辰渊尘 · 2026-05-08 · via
TIP

修改前必读:

  • 本帖基于 Astro框架Fuwari主题 进行修改方案编写,因此请读者优先掌握 Astro Docs 的内容后再来进行魔改。
  • 由于修改内容较多,以及可能会导致意料之外的事情,推荐使用 Github 配合 VSCode 进行修改,方便随时备份恢复

前言#

之前在用 Hexo 的 anzhiyu 主题时,就搞过一次友链状态显示的功能(详见安知鱼主题实现友链状态前端显示),当时用的是 LiuShen 大佬check-flink 方案,效果还不错。

后来博客迁移到了 Astro 框架的 Fuwari 主题,之前那些 Hexo 的东西自然是用不了了。一直惦记着这个功能,趁着有空就把它给搞上了。

实现来自:LiuShen 大佬的友链状态检测方案

解析#

先简单说一下这个功能的原理,其实和之前 anzhiyu 主题那篇是一样的套路:

  1. 后端检测:通过 GitHub Action 定时运行 Python 脚本,访问所有友链站点,记录延迟和可达性
  2. 生成结果:检测结果输出到一个 result.json 文件,部署在 Vercel / Zeabur 等平台
  3. 前端渲染:页面加载时 fetch 这个 JSON,根据延迟数据在友链卡片上显示彩色状态标签

状态颜色分级如下:

  • 绿色(延迟 < 1s):站点响应很快
  • 黄色(延迟 1s ~ 2s):正常速度
  • 橙色(延迟 >= 2s):有点慢
  • 红色(超时 / 不可达):站点可能挂了

修改#

后端配置#

后端检测部分直接使用 LiuShen 大佬的 check-flink 项目,具体部署教程可以参考他的文章,这里就不重复了。你需要做的就是:

  1. Fork 他的仓库
  2. 配置 GitHub Action
  3. 部署到 Vercel / Zeabur,拿到一个可以访问 result.json 的 URL

拿到 URL 后,记下来,后面要用。

友链页改造#

首先需要修改 src/pages/link.astro,给每个友链卡片加上 data-url 属性和状态标签的容器。

<div class="grid grid-cols-1 md:grid-cols-2 gap-4">

{friends.map((friend) => (

<a href={friend.url} target="_blank" class="friend-card">

<a href={friend.url} target="_blank" class="friend-card" data-url={friend.url}>

<span class="friend-status"></span>

<div class="flex items-center gap-2">

然后在 <style> 部分添加状态标签的样式。注意 .friend-card 需要加上 relative 定位,这样状态标签才能相对卡片定位。

// src/pages/link.astro <style>

.friend-card {

@apply flex flex-col gap-1 p-4 rounded-lg bg-[var(--card-bg)] border border-black/10 dark:border-white/10 hover:border-black/20 dark:hover:border-white/20 hover:bg-black/5 dark:hover:bg-white/5;

@apply relative flex flex-col gap-1 p-4 rounded-lg bg-[var(--card-bg)] border border-black/10 dark:border-white/10 hover:border-black/20 dark:hover:border-white/20 hover:bg-black/5 dark:hover:bg-white/5;

transition-property: background-color, border-color, scale;

transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);

transition-duration: 0.15s;

transform: translateZ(0);

}

.friend-status {

position: absolute;

top: 8px;

right: 8px;

font-size: 0.7rem;

padding: 2px 6px;

border-radius: 4px;

color: #fff;

line-height: 1.2;

white-space: nowrap;

display: none;

}

.friend-card:active {

渲染逻辑#

最关键的一步,在 src/layouts/Layout.astro</style> 标签后面添加内联脚本。这里用 is:inline 让脚本直接在客户端执行,不经过 Astro 的打包处理。

</style>

<script is:inline>

function renderLinkStatus() {

if (!document.querySelector(".friend-status")) return;

fetch("https://check-flink.mcxiaochen.top/result.json") // 改成你自己的 URL

.then(res => res.json())

.then(data => {

if (!data.link_status) return;

const statusMap = {};

data.link_status.forEach(item => {

statusMap[item.link] = item;

});

document.querySelectorAll(".friend-status").forEach(el => {

const card = el.closest("[data-url]");

if (!card) return;

const url = card.getAttribute("data-url");

const info = statusMap[url];

if (!info) return;

el.style.display = "inline-block";

if (info.latency === -1) {

el.style.backgroundColor = "#ef4444";

el.textContent = "超时";

} else if (info.latency < 1) {

el.style.backgroundColor = "#22c55e";

el.textContent = info.latency + "s";

} else if (info.latency < 2) {

el.style.backgroundColor = "#f59e0b";

el.textContent = info.latency + "s";

} else {

el.style.backgroundColor = "#f97316";

el.textContent = info.latency + "s";

}

});

})

.catch(err => console.error("friend link status error:", err));

}

function setupLinkStatus() {

renderLinkStatus();

if (window.swup) {

window.swup.hooks.on("page:view", renderLinkStatus);

}

}

if (window?.swup?.hooks) {

setupLinkStatus();

} else {

document.addEventListener("swup:enable", setupLinkStatus);

}

</script>

<script>

这里有一个小细节:Fuwari 主题使用了 swup 做页面过渡动画,所以需要监听 swup 的 page:view 事件,在页面切换后重新渲染状态标签。如果不做这个处理,在友链页和其他页面之间切换时,状态标签就不会刷新。

顺便修的一个小 Bug#

在改的过程中发现 src/layouts/Layout.astro 里的 keywords meta 标签有个小问题 —— 当 siteConfig.keywords 是数组时,直接塞进 content 属性会变成逗号分隔的奇怪字符串。顺手修了一下:

<meta name="keywords" content={siteConfig.keywords}>

<meta name="keywords" content={Array.isArray(siteConfig.keywords) ? siteConfig.keywords.join(', ') : siteConfig.keywords}>

写在最后#

到这里就大功告成了,效果就是在友链卡片的右上角会显示一个小标签,颜色根据延迟自动变化。

好处:

  1. 一目了然:打开友链页就能看到哪些站点正常、哪些挂了
  2. 自动更新:后端 GitHub Action 定时检测,前端实时拉取,不用手动维护
  3. 视觉友好:颜色分级直观,绿色放心、红色警惕

代码是 AI 辅助修改的,如果有问题欢迎评论区指出~

参考资料(排名不分先后)#