友情链接是博客的"社交名片",但手动维护友链总会遇到这些麻烦:对方悄悄删了不知道、想加友链要改主题文件、点击没统计、外链跳转没提示。所以自己开发了 FriendLinks 友情链接插件把这些事都一次性解决了。

一、它能做什么

1. 友链申请与审核

访客可在前台填写申请表(站点名称、URL、Logo、描述、反链检测页面),提交后进入后台审核流程。支持两种模式:

  • 人工审核:申请进入"待审核"状态,管理员手动通过。
  • 自动通过:反链检测成功后直接上线,失败则进入待审核。

申请表内置防滥用:HMAC Token 防 CSRF、蜜罐字段拦机器人、同 IP 每小时限 5 次、URL 去重。
1-013803.jpg

2. 反链自动检测

插件定时去对方站点抓取页面,检查是否真的有指向本站的链接。检测策略可配置:

  • 检测间隔:15 分钟 ~ 7 天可选
  • 连续失败阈值:达到次数自动下线(默认 3 次)
  • 每批检测数量:1~100 条,友链多时分批跑

检测有安全防护:只允许公网 HTTP/HTTPS、不跟随重定向、拦截内网地址、限制响应体 2MB,避免 SSRF 风险。

3. 自动下线与自动上线

  • 自动下线:在线友链连续检测失败达到阈值,自动下线并打标记。
  • 自动上线:下线友链复检成功后自动恢复,删除线和提示文案消失。
  • 手动操作不被覆盖:管理员手动下线或拒绝的友链,不会被自动检测"私自"重新上线。

前台展示也会配合状态:反链失败的友链加删除线、悬停提示"暂未检测到本站友链"、链接强制走安全跳转并加 nofollow
2-013803.jpg

4. 安全跳转与点击统计

点击友链不直接跳走,先到一个中英文确认页,显示目标站点名称和完整 URL,访客点"继续访问"才跳转。

  • 确认页加固:CSP、X-Frame-Options、Referrer-Policy 等安全头齐全。
  • Token 绑定 link_id 和目标 URL,防止篡改。
  • 仅在确认继续后才记录点击,避免爬虫刷假数据。
  • IP 默认脱敏存储(隐藏最后两段),可切换完整模式。

后台"访客记录"页可查看点击时间、友链名称、IP、User-Agent、来源页,支持按保留期自动清理。

5. 分类管理

一个友链可属于多个分类,主题用"调用标识"(slug)调用:

\TypechoPlugin\FriendLinks\Plugin::render(['categories' => ['tech', 'friends']]);

没有分类的友链自动归入"默认分类"。删除分类不删除友链,只解除关联。后台支持批量追加/移出/替换分类,事务保存。

6. 批量操作

列表页可勾选多条友链,批量审核通过、拒绝、下线、删除,或调整分类。批量删除需二次确认。

7. 单条展示选项

每条友链可单独配置:

  • 是否添加 nofollow
  • 链接方式:安全跳转 / 站点原链接 / 跟随全局

8. 定时任务

提供两种调度方式:

  • 访问触发(默认):站点访问时轻量兜底执行。
  • 独立 Cron URL(推荐):插件设置页生成带 Token 的地址,加到服务器 crontab 即可。
    3-013803.jpg

    二、怎么用

安装

  1. FriendLinks 目录放入 usr/plugins/
  2. 后台启用"友情链接"插件。
  3. 在插件设置中确认本站名称、本站链接、检测策略。
  4. 在"管理 → 友情链接"添加或审核友链。

激活时自动建表,无需手动操作 SQL。

主题调用

最简单的调用,一行搞定:

<?php \TypechoPlugin\FriendLinks\Plugin::render(); ?>

输出申请表:

<?php \TypechoPlugin\FriendLinks\Plugin::renderApplyForm(); ?>

按分类输出:

<?php \TypechoPlugin\FriendLinks\Plugin::render(['categories' => ['tech']]); ?>

完全自定义 HTML:

<?php foreach (\TypechoPlugin\FriendLinks\Plugin::getLinks() as $link): ?>
    <a href="<?php echo \TypechoPlugin\FriendLinks\Plugin::escape(\TypechoPlugin\FriendLinks\Plugin::linkUrl($link)); ?>"
       rel="<?php echo \TypechoPlugin\FriendLinks\Plugin::escape(\TypechoPlugin\FriendLinks\Plugin::linkRel($link)); ?>">
        <?php echo \TypechoPlugin\FriendLinks\Plugin::escape($link['site_name']); ?>
    </a>
<?php endforeach; ?>

侧边栏集成

在默认主题 sidebar.php 中:

<?php if (in_array('ShowFriendLinks', (array)$this->options->sidebarBlock, true)
    && class_exists('\TypechoPlugin\FriendLinks\Plugin')
    && \TypechoPlugin\FriendLinks\Plugin::getLinks()): ?>
    <section class="widget">
        <h3 class="widget-title"><?php _e('友情链接'); ?></h3>
        <?php \TypechoPlugin\FriendLinks\Plugin::render(); ?>
    </section>
<?php endif; ?>

再到主题 functions.phpsidebarBlock 选项里加入 'ShowFriendLinks' => _t('显示友情链接'),即可在外观设置里开关。

配置 Cron(可选)

插件设置页会生成一个带 Token 的 URL,复制后加到服务器 crontab:

*/10 * * * * curl -fsS "https://example.com/action/friend-links?do=cron&token=YOUR_TOKEN" >/dev/null

Token 只应保存在服务器计划任务中,不要公开。

三、设计上的几个小心思

  • 禁用默认保留数据:避免误操作丢友链,需在设置里明确选择"禁用时删除"才会清表。
  • 平滑升级:新增字段时自动 ALTER TABLE,不用禁用插件再启用。
  • 多数据库支持:兼容 MySQL、PostgreSQL、SQLite。
  • 调用代码生成器:后台"调用代码 Tab"可根据选择直接生成五种模板代码,复制即用。
  • IP 脱敏:默认隐藏最后两段,切回完整模式只对新记录生效,历史数据不回写。

插件发布地址FriendLinks:让 Typecho 友链管理更省心的插件


插件信息:FriendLinks v1.0.0 · 兼容 Typecho 1.3.x · 作者:欧阳博客 (https://www.oyzm.cn)

标签: typecho, 友链, 插件

添加新评论