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

推荐订阅源

爱范儿
爱范儿
Simon Willison's Weblog
Simon Willison's Weblog
K
Kaspersky official blog
P
Palo Alto Networks Blog
Google DeepMind News
Google DeepMind News
www.infosecurity-magazine.com
www.infosecurity-magazine.com
AI
AI
G
GRAHAM CLULEY
O
OpenAI News
Application and Cybersecurity Blog
Application and Cybersecurity Blog
Help Net Security
Help Net Security
L
LINUX DO - 热门话题
S
Schneier on Security
P
Privacy International News Feed
L
Lohrmann on Cybersecurity
SecWiki News
SecWiki News
C
Cybersecurity and Infrastructure Security Agency CISA
T
Threatpost
C
Cyber Attacks, Cyber Crime and Cyber Security
A
Arctic Wolf
C
Cisco Blogs
V2EX - 技术
V2EX - 技术
有赞技术团队
有赞技术团队
Apple Machine Learning Research
Apple Machine Learning Research
月光博客
月光博客
Latest news
Latest news
人人都是产品经理
人人都是产品经理
Schneier on Security
Schneier on Security
Last Week in AI
Last Week in AI
Webroot Blog
Webroot Blog
美团技术团队
N
News and Events Feed by Topic
大猫的无限游戏
大猫的无限游戏
Security Archives - TechRepublic
Security Archives - TechRepublic
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
博客园 - 三生石上(FineUI控件)
The Cloudflare Blog
Project Zero
Project Zero
博客园_首页
Cloudbric
Cloudbric
IT之家
IT之家
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
雷峰网
雷峰网
罗磊的独立博客
Hacker News: Ask HN
Hacker News: Ask HN
The Last Watchdog
The Last Watchdog
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
T
Tenable Blog
Scott Helme
Scott Helme

辰渊尘站

713解锁节来辣!小米17全系,k90pm又能解bl了 - 辰渊尘站 服务器面板迁移:从宝塔到 1Panel - 辰渊尘站 Subconverter 太臃肿?PHP 版轻量化替代来了! - 辰渊尘站 Astro框架Fuwari主题侧边栏添加Umami访问统计 Astro框架Fuwari主题侧边栏添加Umami访问统计 为Fuwari框架适配友链状态显示 免费领取网易云音乐7天会员 免费领取网易云音乐7天会员 小米MiMo Token Plan免费送辣! 小米MiMo Token Plan免费送辣! Astro框架Fuwari主题实现仿hexo-abbrlink功能 Astro框架Fuwari主题实现仿hexo-abbrlink功能 观《鬼灭之刃:无限城篇 第一章 猗窝座再袭》首映有感 观《鬼灭之刃:无限城篇 第一章 猗窝座再袭》首映有感 为你anzhiyu主题的Twikoo评论系统恢复预览按钮 为你anzhiyu主题的Twikoo评论系统恢复预览按钮 山东泰安泰山游记:煌煌泰山景,谦谦君子风 山东泰安泰山游记:煌煌泰山景,谦谦君子风 安知鱼主题:修复背景图修改引发的深色模式可读性问题 安知鱼主题:修复背景图修改引发的深色模式可读性问题 安知鱼主题实现友链状态前端显示 安知鱼主题实现友链状态前端显示 我敲!优选DNS牛大了 我敲!优选DNS牛大了 安知鱼主题侧边栏添加无聊湾 安知鱼主题侧边栏添加无聊湾 从零开始使用Hexo框架搭建属于你的博客(一)环境准备篇 从零开始使用Hexo框架搭建属于你的博客(一)环境准备篇 记录下Hexo博客从本地构建迁移到Netlify,AI API Key 泄露问题与解决方案记录 记录下Hexo博客从本地构建迁移到Netlify,AI API Key 泄露问题与解决方案记录 云服务器宝塔部署Twikoo博客评论系统 云服务器宝塔部署Twikoo博客评论系统 手把手教你在Linux系统下部署MCSManager并搭建一个MC服务器 手把手教你在Linux系统下部署MCSManager并搭建一个MC服务器 为你的Twikoo添加酷安表情包 为你的Twikoo添加酷安表情包 记录一次博客评论迁移过程 记录一次博客评论迁移过程 记一次花嫁联名借记卡申领过程 记一次花嫁联名借记卡申领过程 为使用anzhiyu主题的博客加上十年之约进度条 为使用anzhiyu主题的博客加上十年之约进度条 有关建站一个月以来的一点点感想和后续计划 有关建站一个月以来的一点点感想和后续计划 这可能是iOS自签的版本答案,二合一LiveContainer教程来辣! 这可能是iOS自签的版本答案,二合一LiveContainer教程来辣! iOS侧载新选择!SideStore+LiveContainer,纯净无广,无限安装软件!!! iOS侧载新选择!SideStore+LiveContainer,纯净无广,无限安装软件!!! 从零开始使用Hexo框架搭建属于你的博客(零)准备篇 从零开始使用Hexo框架搭建属于你的博客(零)准备篇 Arch Linux+Hyprland从安装到使用只需这一篇(保姆级喂饭超全教程) Arch Linux+Hyprland从安装到使用只需这一篇(保姆级喂饭超全教程) - 辰渊尘站 恭喜你找到了本站的第一篇文档 恭喜你找到了本站的第一篇文档 - 辰渊尘站
为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 辅助修改的,如果有问题欢迎评论区指出~

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