11 月 16 号,上海金山,下午三点。

今天本来排的不是这个题。原来准备写的是那两个站里比较硬的一个——106 个 .bak 文件在公网裸奔、后来怎么用 rsync 挪走。但昨天下午我把首页的友情链接点了一遍,点出点意外,索性先把这件事写掉。素材是热的,隔一天再还原,细节就假了。

一、先点一下自己挂出去的链接

首页最底下有一块「友情链接」,很小,两张卡片。一张写着「小叶同学」,昨天刚加上去的;另一张写着「Luxe Wallpaper」,下面一行小字「自研动态桌面引擎」。这张在页面上挂了两个月。

我点它。

转了大概十几秒,浏览器给我一句话:520 Origin Error。

二、520 不是我的错,但它跟死链没区别

把命令和响应头抄下来:

curl -sS -o /dev/null -D - https://luxe.covps.cn/

HTTP/1.1 520 Origin Error
Server: ESA
Content-Length: 0
Connection: keep-alive

Server 是 ESA,阿里云边缘安全加速那套。520 这个码是 Cloudflare 系的语言,意思很直白:边缘节点活得好好的,我收到你的请求了,但我去回源拿东西,拿不回来。

要紧的不是错误码,是 Content-Length: 0。一个字节都没有。连个红色报错页都不给我,就是空。

我怕是自己的网络抽风,又连发了两次。

第 1 次 → http_code=520  size=0
第 2 次 → http_code=520  size=0
第 3 次 → http_code=520  size=0

三次,一模一样。这不是抽风,是断了。

三、把能想到的路径都试了一遍

万一是首页坏了,友链页还在呢?我就顺着常见路径挨个戳:

/            -> 520  0B
/links       -> 520  0B
/links/      -> 520  0B
/friends     -> 520  0B
/friends/    -> 520  0B
/youlian     -> 520  0B
/link        -> 520  0B
https://www.luxe.covps.cn/ -> 000(连不上)
http://luxe.covps.cn/      -> 301(跟过去一样是 520)

全 520,全 0 字节。www. 版本更彻底,连接直接被拒,返回码 000。

所以问题不在某个路径上,是整站回源断了。这种时候你能做的其实只有一件事:等它自己恢复,或者承认它没了。

四、我想验证它有没有回链,但我连门都进不去

按我自己的规矩,友链是要看回链的——你挂我,我挂你,这才叫交换。我之前给首页这两个链接都留了活口,只要对面挂了 moxiaoa.com,我就留着。

现在的问题是:我连它的页面都看不到。它有没有友链页、页面上有没有我那四个字、什么时候加的、加在哪儿,我一个都验证不了。

验证不了的东西,按没交钱处理。删了。

删之前留了备份,就改那一处:

改前:/tmp/bak_20261114/index-before-yesir.html
改后:首页 friendlinks 区块
  <a href="https://luxe.covps.cn/">Luxe Wallpaper / 自研动态桌面引擎</a>  → 整条移除

改完扫一遍全站 73 个地址的外部链接,moxiaoa 之外的只剩三条:miaoda.feishu.cn(文章里引用的一个文档)、example.com(示例代码)、blog.yesir.ink。covps 残留 0 处。

五、这件事最让我难受的,不是我删了一个站

是我挂了两个月,一次都没点过。

友情链接在页面上是一个 <a> 标签。只要它还印在那儿、字色正常、鼠标上去变成小手,从视觉上它跟"活着"没有任何区别。它不会自己变灰,不会自己报错,不会给你发一封邮件说"我挂了"。

我这两个月每天写文章、每天推十条收录、每天看蜘蛛日志,唯独没看过自己首页那两张卡片背后是什么。

做新站最怕的其实不是被拒绝,是「看起来活着」。这条友链在我页面上就是活着的。实际上它可能一个月前就死了,只是我一厢情愿地认为它还在。

六、第二个站,curl 只肯给我 689 字节

你给的是 https://blog.yesir.ink。

我先用最笨的办法验它活没活:

curl -s https://blog.yesir.ink/ -o ys.html
wc -c ys.html
689 ys.html

689 字节。这个数字不对劲。一个博客首页,光导航栏加文章列表就不止这些。

打开文件看:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <link rel="icon" href="/favicon.ico" />
    <script>
      window.AliyunCaptchaConfig = {
        region: 'cn',
        prefix: '1pwq65',
      };
    </script>
    ...
</head>
<body>
  <div id="app"></div>
</body>
</html>

一个 Vue 的空壳。整个页面除了一个挂载点和一个阿里云验证码 SDK,没有别的东西。标题是 YeSir,正文一个字都没有。

这里得到一个很实用的结论:curl 能验"活着",验不了"有内容"。单页应用不管你请求哪个路径,回来的都是同一个壳,689 字节,每次都一样。拿它判断对面死没死,是不够的;拿它判断对面有没有内容,更不够。

七、用浏览器渲染,才看到一个真的人

换成真浏览器打开,页面撑起来了。一条一条抄:

标题      YeSir
导航      首页 / 文章 / 日常 / 友链 / 留言 / 关于
自述      小叶同学
副题      路漫漫其修远兮,吾将上下而求索
页脚      © 2026 我的博客 | 用心记录生活
运行时长   25 天 14 时 39 分 57 秒
文章分类   随手 0 篇 · 生活日常 1 篇 · 技术分享 0 篇
备案      苏ICP备2026087297号-1
技术栈     SpringBoot + Vue

这个站的画像一下就清楚了:建站 25 天,1 篇文章,1 个作者,认真去做了备案,设计是黑白配色,页脚写「用心记录生活」。

比我这个站还新。我已经 61 篇,索引还是 0。它 1 篇,但页面做得比我好看。

八、找它的友链页,花了我十分钟

导航上有「友链」,我点进去。

404。

试 /links,404。/index/friendlink,还是 404。

这个站的路由是前端控制的,document.querySelectorAll('a') 抓出来只有空链接、mailto、javascript:void 和一个备案链接——导航栏那六个字根本不是真链接,是 JS 触发的路由。

最后我从它的打包文件里翻路由表:

curl -s https://blog.yesir.ink/assets/index.44b21b47.js -o yesir.js
wc -c yesir.js
2232898 yesir.js

grep -o 'path:"[^"]*"' yesir.js | sort -u
path:"about"
path:"article"
path:"daily"
path:"feedback"
path:"friendlink"
path:"/friendlink"
path:"/index"
...

两兆的 JS,从里面挑出来一个 friendlink。真实地址是 https://blog.yesir.ink/friendlink。

这办法很土,但它有效。遇到一个前端路由写得规规矩矩、又没做 sitemap 的站,这是唯一能拿到真地址的路。

九、打开以后,我有点不好意思

页面结构是两块:上面「已通过友联 4」,下面一长串申请列表。

「已通过」第一张卡片写着:

陌笑技术分享
记录技术路上的每一点收获

再往下拉,申请列表里有一条,状态「已通过」,申请时间 2026-11-14。

也就是说,昨天我还在纠结"它就 1 篇文章,要不要加",它已经把我审核通过,还挂在第一的位置上。

友链这事的正序,一般是我先挂你、你审核我,或者两家同时。它把顺序反过来了:先通过我,挂着等我回。

这不算什么问题,只是让人有点不好意思——我先看了它的篇数,它先看了我的内容。

十、顺手发现,我们站根本没有友链页

它那个 /friendlink 让我起了个念头:我们自己的友链页在哪?

/links.html    -> 404
/links/        -> 404
/friends.html  -> 404
/friends/      -> 404
/link.html     -> 404
/youlian.html  -> 404

六个 404。

我站上 61 篇文章、73 个 sitemap 地址,从来没有一个页面是给友链用的。所有交换全靠谁问我就口头回一句,然后改首页。

顺手还查出两个:favicon.ico 是 404,assets/logo.png 也是 404。浏览器标签页上一直是那个默认的空白图标,我用了两个月没注意过。

昨天下午就把 /links.html 做出来了。CSS 直接复用 /seo/ 那一页的骨架,实测 7951 字节,四块内容:交换条件、本站信息(一段可以整段复制的 pre 块)、怎么申请(微信 lige0552,备注写「友链」,48 小时内回)、现在的伙伴。

加进导航之后,sitemap 从 72 条变成 73 条。

十一、门槛这条,我自己改了口径

友链页上原来写着六条条件,第一条是「个人博客或技术类站点,有实质原创内容,至少 10 篇」。

小叶同学 1 篇。按字面,它不达标。

但我还是加了。因为它是我挑的,我看过它长什么样。

标准这东西,是拿来筛陌生人的,不是拿来筛自己判断的。别人来敲门,我需要一条能执行、能当面说清楚的线;我自己挑中的,我看过它长什么样,篇数不构成理由。

所以我在条件列表后面补了一段,原话是:

这套条件是用来筛陌生来站的。我自己挑中、主动去加的站不在此列——我看的是内容和人,不是篇数。反过来,别人来申请,就按上面这几条走,一条不满足我不加。

说得直白点,这等于给自己留了个后门。以后真有人问"凭什么它 1 篇能进、我 20 篇进不来",我唯一的回答是"凭我自己看过"。这个理由不好听,但它是真的,比编一个"它内容质量高"要诚实。

十二、友链到底对收录有没有用

这个问题被问过好几次,昨天我自己又想了一遍。

我这一个月的账是这样的:每天 10 条主动推送;11-13 单日实抓 206 次、覆盖 61 个页面;抓取上限 184 次已经顶格;四类抓取异常全是 0;索引量连着 11 天全是 0。

从这些数字看,百度不是没来,是来了不收录。

友链能做的三件事:给蜘蛛一条发现路径;偶尔让它顺路爬一次;理论上一点权重传递——但新站之间这一点,接近于零。

友链做不到的:它不会因为你多挂了十个链接,就让你进索引。

如果索引本身就是 0,问题不在外链。我这两个月把 canonical、keywords、外链为零、抓取质量一项一项都排掉了,最后卡在索引层。要动它,只能等平台工单,或者等站龄。

所以友链该做,做,但别把它当药吃。它不是药,它是个礼貌。

十三、今天动了什么,改前改后

位置改前改后
首页 friendlinks 区块1 条:Luxe Wallpaper2 条:小叶同学 + 更多伙伴(跳 /links.html)
/links.html不存在(404)7951 字节,HTTP 200,canonical 自指
sitemap.xml72 个 loc73 个 loc
首页文章卡片61 张61 张(未受影响)

改完的线上验证:

curl -s --compressed -o /dev/null -w '%{http_code} %{size_download}\n' https://www.moxiaoa.com/links.html
200 3654        ← gzip 后的传输体积,原始文件 7951 B

首页:blog.yesir.ink 出现 1 次 / covps 残留 0 次 / href="/links.html" 1 次
sitemap:loc 73,含 links.html
文章卡片:61 张,与改前一致

有一件事值得记一笔:nginx 开了 gzip,curl 不带 --compressed 时拿到的 size_download 是压缩后的大小。我这次改文件是用 sftp 从服务器拉的原始文件做的基底,不是 curl 下来的——拿压缩内容当底改,改完就是一堆坏字节。

十四、最后

一个 520 教给我的,不是我该删谁,是我该点一遍自己挂出去的东西。

从下个月起,我给自己定一条:每月最后一天,把首页的友链从头点一遍。打不开的、内容变成赌博站的、半年没更新的,一律清。守着几十条死链不动,除了让页面显得热闹,没有别的作用。

站点上现在 61 篇,编号到 65(18、19、56 是空号,不是丢了什么)。想聊友链这块,站内没有评论区,微信 lige0552。