RSS 源做对了才有用:输出条数、分类过滤、绝对链接与缓存头四件事

一、RSS 不是"老古董",它是最便宜的分发通道

在一个所有人都盯着平台算法的年代,RSS 看起来像上个世纪的东西。但对一个个人站长来说,它有一个别人给不了的好处:它不依赖任何平台的推荐逻辑,订阅关系只存在你和读者之间。你发一篇新文章,订阅者的阅读器就会收到,中间没有平台抽成,也没有限流。

而且 RSS 对搜索引擎也不完全是废物。虽然搜索引擎已经很少把 RSS 当作主要的发现渠道,但很多聚合服务、内容监控工具、行业资讯站点仍然在抓 RSS。写好一个 feed,等于给自己的文章多开了一扇门,而成本只是一次配置。

问题在于,大多数站点的 RSS 是"框架默认"的产物:全站最新 10 篇、全文或摘要、没有分类过滤。这样的 feed 对老读者没什么用,因为它把评论、标签页、翻页都混了进来。这篇文章讲的是一套完整的 RSS 配置,包括输出什么、输出多少、以及如何利用它做收录辅助。

二、Typecho 的 feed 机制与改写入口

Typecho 的 feed 路径是 /feed/,也支持 /feed/category/分类缩略名/ 这种按分类过滤的形式。它在主题的 functions.php 里可以接管输出,方法是通过 Widget_Archive 的 feed 方法或者直接在主题里定义 feed 模板。

先在浏览器里打开 https://你的域名/feed/,看它输出什么。常见的问题有三个:一是输出全文,导致整个 feed 有几兆;二是输出的时间格式是 RSS 规范的 RFC 822,很多工具不认识带时区的写法,需要确认;三是输出的链接是相对路径或者 localhost,这是站点地址没设置对。

检查 feed 的合法性,最直接的办法是用 xmllint:

curl -s 'https://example.com/feed/' -o /tmp/feed.xml
xmllint --noout /tmp/feed.xml && echo 'XML OK'
xmllint --format /tmp/feed.xml | head -60

如果输出 OK,说明结构没错。接下来看内容。如果你发现 <link> 是相对路径,那问题出在后台设置里的"站点地址"没有写完整域名,或者主题里用了 $this->options->siteUrl 但没有 rtrim 处理斜杠。

三、输出多少条:10 条、20 条还是全量

这个数字没有标准答案,但有一个取舍逻辑。条数太少,读者如果一周不上阅读器,中间的文章就永久错过了,因为 feed 只保留最新的 N 条,过期的不会补发。条数太多,feed 文件体积变大,每次刷新都要下载几兆,移动端读者体验很差。

对每天更新 1~3 篇的站点,20 条大约覆盖一周到两周,是一个合理的默认值。对每天更新十几篇的站点,20 条只覆盖一两天,读者的阅读器会很吵。这时候更好的做法是按分类拆分 feed:把"教程"类做成一个低频 feed,"随笔"做成另一个。读者可以只订自己关心的那条。

Typecho 支持按分类的 feed,路径形如 /feed/category/tech/,其中 tech 是分类的缩略名。这一步很值得做,因为它把"订阅"变成了"选择订阅",读者的留存会明显更好。

如果想让每条 feed 里的描述是摘要而不是全文,可以在主题里截断:

// functions.php 里对 feed 内容截断
function truncate_feed_content($content) {
    $text = strip_tags($content);
    if (mb_strlen($text, 'UTF-8') > 200) {
        $text = mb_substr($text, 0, 200, 'UTF-8') . '……';
    }
    return $text;
}

摘要的副作用是把读者推回站内,好处是能看广告和统计;全文的好处是阅读体验好,但会让部分读者永远不打开你的网站。个人站通常选摘要,因为流量统计和广告曝光是真实的生存需求。

四、feed 里的图片、相对链接与字符集

RSS 输出里最容易出问题的不是结构,而是内容。第一个坑是相对链接:正文里的 src="/upload/1.jpg" 在阅读器里会变成 https://阅读器域名/upload/1.jpg,全部 404。修法是在输出 feed 之前把相对路径补成绝对路径:

function abs_urls_in_feed($content) {
    $site = rtrim(Helper::options()->siteUrl, '/');
    $content = preg_replace('#(src|href)=(["\'])/(?!/)#i',
        '$1=$2' . $site . '/', $content);
    return $content;
}

第二个坑是字符集。如果你的站点是 UTF-8,而 feed 声明是 ISO-8859-1,中文会变成乱码,阅读器里看到一堆问号。用 xmllint 或者 file -i /tmp/feed.xml 确认编码,输出头里必须有 <?xml version="1.0" encoding="UTF-8"?>。

第三个坑是CDATA 与转义。feed 的 description 通常包在 <![CDATA[...]]> 里,如果正文本身含有 ]]> 这个序列(比如代码块里写 SQL 或者 PHP 的闭括号),CDATA 会提前结束,整个 XML 就坏了。这是个典型的隐蔽错误,平时不出现,某篇技术文章里带了代码就炸。稳妥的写法是不用 CDATA,而是走 XML 转义,或者对内容里的 ]]> 做替换。

五、用 feed 做收录的辅助:不只是给读者看

搜索引擎确实不太依赖 RSS 了,但有几类服务还在用:行业资讯聚合站、内容监控工具(比如某些舆情监控)、以及一部分新闻类应用。这些渠道带来的流量不大,但对于垂直领域的技术站,一个被行业聚合站收录的文章,可能带来几个高质量的访问者。

更实际的用法是用 feed 做内容的"对外快照"。你的站点被某些工具抓取了文章,别人抄你的内容时,feed 的时间戳就是最早的证据。很多站长在做原创维权的时候,发现自己的 feed 快照比对方文章的发布时间早,这就是有效的证据链之一。

还有一个用法是自己订阅自己。用一个阅读器订阅自己的 feed,你能看到的正是读者看到的样子,能第一时间发现图片裂了、摘要乱码了、链接错了。这种"自测"的成本极低,效果却比任何检查工具都直接。

把 feed 提交到几个还在用的聚合服务,也值得花十分钟做一次,比如一些技术社区有自己的 RSS 收录入口。这些入口的价值不在于大量流量,而在于多一条被发现的路径。收录这件事,本质上是"被发现的机会数"的累积。

六、验收:四个必须检查的点

第一,feed 能被主流阅读器正常解析。用 Feedly 或者本地的 RSS 阅读器订阅一次,看条目是否正确。第二,图片能正常显示。在阅读器里找一篇有图的文章,确认图片不是破图。第三,时间戳是本地时间还是 UTC。RSS 的时间格式必须是 RFC 822,如果输出的是 ISO 8601,部分工具会解析失败。第四,分类过滤的 feed 是否真的只包含该分类。

这四个点检查一次,大约只要十分钟,能避免掉大部分"我的 RSS 订不了"的反馈。检查的时候建议用一个干净的邮箱和一台没装过插件的阅读器,避免本地缓存干扰判断。

另外还有一个容易被忽略的检查项:feed 的 HTTP 响应头。有些站点在 Nginx 或者 CDN 上设置了 Cache-Control: max-age=3600,结果新文章发布后一小时阅读器还看不到。feed 是一个必须实时的资源,正确的做法是对 /feed/ 单独设一个很短的缓存时间,比如 60 秒,或者干脆不缓存。

location = /feed/ {
    add_header Cache-Control "public, max-age=60";
    # 其余按正常 fastcgi 处理
}

如果你用了 CDN,还要在 CDN 侧对 /feed/ 路径设置"不缓存"或者"缓存 60 秒"。很多站长反馈"我发了文章但订阅者看不到",查到最后都是这一条,而不是 Typecho 的问题。

顺带说一句 ETag 与 Last-Modified。feed 是动态生成的,If-Modified-Since 的处理如果写错,阅读器可能一直拿到 304 而看不到更新。检查方法是发布一篇新文章之后,用 curl -I 看 feed 的 Last-Modified 有没有变。如果不变化,说明生成 feed 的代码没有更新时间戳,这时候阅读器会被误导。

七、让读者真的能订阅:把入口做出来

配置好 feed 之后,还有一步经常被跳过:在页面上放订阅入口。很多站的 feed 是能用的,但从来没有人知道它存在。在侧栏或者页脚加一个小小的 RSS 图标,链接到 /feed/,再配一句"用阅读器订阅本站",这就够了。不需要弹窗,不需要订阅引导页。

更细一点的做法是加上 autodiscovery 标签,让浏览器和阅读器自动发现你的 feed:

<link rel="alternate" type="application/rss+xml"
      title="博客全文 RSS" href="https://example.com/feed/">

这个标签放在 <head> 里,浏览器地址栏会出现 RSS 图标,读者点一下就能订阅。有些阅读器还支持直接粘贴站点首页 URL 自动发现 feed,靠的就是这个标签。少这一行,很多自动化工具就找不到你的 feed。

八、小结

RSS 不是一个过时的技术,而是一个被低估的分发通道。对个人站长,它的价值在于"掌控":读者列表在你手上,不在平台手上。把 feed 的输出条数、分类过滤、链接绝对化、编码、缓存这几件事做对,你就多了一个稳定的、不依赖算法的读者入口。这件事花不了半天,但它带来的自主性,比买流量更值钱。

如果只能做一件事,那就先做分类 feed:它把"订阅全部"变成"订阅我关心的那个栏目",是订阅转化率提升最明显的一步。

Last modification:November 11th, 2026 at 09:25 pm

Leave a Comment