diff options
| author | eltrac <hi@eltr.ac> | 2026-03-10 22:00:25 +0800 |
|---|---|---|
| committer | eltrac <hi@eltr.ac> | 2026-03-10 22:00:25 +0800 |
| commit | 9b16ecf2b1e12b19eab843832e2d6393158b83f4 (patch) | |
| tree | e91574c9db344d7b01c86c39e9f898e7ff3e6b80 /content/article | |
| parent | 8edc9c8882f09eb955e33279b7fb9f5fe70f417e (diff) | |
docs: update draft
Diffstat (limited to 'content/article')
| -rw-r--r-- | content/article/webmention.md | 235 |
1 files changed, 233 insertions, 2 deletions
diff --git a/content/article/webmention.md b/content/article/webmention.md index ff822909..4dd39476 100644 --- a/content/article/webmention.md +++ b/content/article/webmention.md @@ -99,7 +99,7 @@ POST https://webmention.app/check/?url=https://my.site/post-xxx ### 使用 webmention.io -最简单也是最常用的第三方 Webmention 接收服务是 [webmention.io](https://webmention.io/),我也在使用。这个服务是开源的,所以还算值得信赖。要使用他们的服务,你首先需要配置 [IndieAuth](https://indieauth.com/),也就是表明你是这个网站的主人,怎么做到呢? +最简单也是最常用的第三方 Webmention 接收服务是 [webmention.io](https://webmention.io/),我也在使用。这个服务是免费且开源的,所以还算值得信赖。要使用他们的服务,你首先需要配置 [IndieAuth](https://indieauth.com/),也就是表明你是这个网站的主人,怎么做到呢? 在网站的 `<head>` 添加: @@ -111,7 +111,7 @@ POST https://webmention.app/check/?url=https://my.site/post-xxx 把 `alice` 改成你自己的用户名。这个标记的意思是,这个网站的主人有 GitHub、Twitter 和电子邮箱账号,用户名或地址如上。接下来,确保你的 Twitter 账号页面或 GitHub 账号资料里有链接到这个网站。这样一来,你就证明了自己拥有这些账号,IndieAuth 也就允许你用这些账号登录。你不必配置全部三个账号,只需要一个有效的登录方式。如果是邮箱的话,IndieAuth 就会给你发送一封电子邮件确认登录。 -你还可以把 `<link>` 写成 `<a>` 标签,如果网页里已经有这些账号页面的链接了,只需要给 `<a>` 加上 `rel="me"` 即可。这种标记方式叫作 microformats,是一种开放标准,后文还会提到。 +你还可以把 `<link>` 写成 `<a>` 标签,如果网页里已经有这些账号页面的链接了,只需要给 `<a>` 加上 `rel="me"` 即可。这种标记方式叫作 microformats,后文还会提到。 配置好 IndieAuth 之后,在 [webmention.io](https://webmention.io/) 输入域名登录,接下来会进入仪表盘。现在,你需要在 `<head>` 里面指定 webmention.io 作为接收器,添加这段内容: @@ -123,9 +123,240 @@ POST https://webmention.app/check/?url=https://my.site/post-xxx 接下来 webmention.io 就能够帮你接收 Webmention 了。这个服务是 [Aaron Parecki](https://aaronparecki.com/) 提供的,如果你觉得不错,可以去支持他!他还是 IndieWebCamp 的创始人和 OAuth 工作组的编辑者。 +好了,现在你能接收 Webmention 了,数据存放在 webmention.io 的服务器里,要怎么查看接收到的 Webmention 呢?有这样几种方式: + +1. 在[仪表盘](https://webmention.io/dashboard)查看最近的 Webmention。 +2. 在[设置](https://webmention.io/settings)获取 RSS/Atom 订阅源,使用 RSS 阅读器查看。 +3. 配置 [Webhook](https://webmention.io/settings/webhooks),在有新 Webmention 时向指定 URL 发送 HTTP 请求,可以配合 [Bark](https://github.com/Finb/Bark) 或 [ntfy](https://ntfy.sh/) 推送到你的手机上。 +4. 通过 [API](https://github.com/aaronpk/webmention.io#api) 获取数据。 + +如果你想通过 API 把 Webmention 展示在自己的网站上,最简单的方法是使用 [webmention.js](https://github.com/PlaidWeb/webmention.js/)。把 JavaScript 文件放在自己的网站上之后,在需要显示 Webmention 的地方添加: + +```HTML +<div id="webmentions"></div> +<script src="/path/to/webmention.min.js" async></script> +``` + +具体的使用方式见项目文档。 + +如果能力允许,可以自己编写渲染逻辑,毕竟 API 已经有了。 + +### 自托管 Webmention 接收端 + +webmention.io 很好用,配合 webmention.js,甚至不需要自己写一行代码,不需要部署任何服务,就能接收并展示 Webmention,这对大部分人来说已经够了。不过,如果你很在乎自己的数据,并希望尽可能少依赖第三方服务,那么你大概要自己部署接收端了。 + +在可以自己部署的 Webmention 接收端中,使用者比较多的是 Horst Gutmann 维护的 [webmentiond](https://github.com/zerok/webmentiond/),用 Go 编写,存储基于 SQLite,简单轻量。此外还有用 Rust 编写的 [WesleyAC/webmention-receiver](https://github.com/WesleyAC/webmention-receiver) 和用 Python 编写的 [capjamesg/webmention-receiver](https://github.com/capjamesg/webmention-receiver)。 + +对于重复造轮子这件事,我们国人也是不输(奇怪的比较)。[Chlorine](https://chlo.is/) 不久前用 Rust 写了一个 Webmention 接收端,名为 [CircleAt](https://codeberg.org/chlorine/circleat),而我也用一门 Lisp 方言开发了 [Weepinbell](https://codeberg.org/eltrac/weepinbell),最近才发布 [v0.1.0](https://codeberg.org/eltrac/weepinbell/releases/tag/v0.1.0) 版本。不过我不建议你用 Weepinbell,因为还没有正式投入使用,可能存在一些问题,进入稳定版本之后我会再发一篇文章的。当然,如果你愿意贡献的话,我将感激不尽。 + +在开始之前,我得警告读者,Webmention 作为一门小众技术标准,使用者很少,自托管接收器的更少,如果遇到问题,可能很难找到解决方案和能够提供帮助的人(虽然我很欢迎有人来问我啦)。如果对自己的技术没什么信心,webmention.io 已经很好了,比能够自托管的选项都要成熟不少。 + +不过剩下的我也没什么好讲的了,如果你决定自托管,那就选择一个自己觉得不错的接收端软件部署到服务器上。至于如何查看接收到的 Webmention 和如何展示,不同的接收端都有实现细节上的不同,这里略过。 + ## 让 Webmention 生动起来:microformats +[microformats](https://microformats.org/) 是一系列开放数据格式,建立在已被广泛采用的标准之上(比如 HTML)。它并不是和 Webmention 强绑定的,实际上 Webmention 标准完全没有提到过 microformats,只不过 IndieWeb 上的人很喜欢把它和 Webmention 一起用。说起来,应该是 webmention.io 的维护者 Aaron Parecki 带的头,webmention.io 默认支持解析 microformats。 + +由于没有 microformats 也不影响使用 Webmention,如果你不感兴趣的话,可以跳过这一节。 + +### microformats 是什么? + +回答这个问题之前,先要了解它解决了什么问题。 + +网页可以是任何东西,可以是 Web 应用(比如 Notion 这样的在线笔记),可以是小工具(比如计算器、格式化工具、视频下载器),可以是相册,也可以是一篇文章,可以是日历。同一张网页也可能包含各种各样的东西,一篇博客文章中有页面标题、主体内容、标签、评分、回复等等。 + +网页的具体结构也是不确定的,为了实现不同的排版和效果,不同网站的 HTML 结构完全不同。有的可能是这样的: + +```HTML +<main id="container"> + <h1 id="post-title">Title</h1> + <article id="post-content"> + <p>Content</p> + <!-- ... --> + <p>Author is ..., follow me on <a href="https://mastodon.social/@author">Mastodon</a></p> + </article> + <div id="comment"> + <!-- ... --> + </div> +</main> +``` + +也有可能是这样的: + +```HTML +<main id="container" class="flex justify-center items-center my-10 mx-auto p-4"> + <header class="max-h-lg shadow-lg"> + <div class="rd overflow-hidden"> + <img src="/posts/xxx/banner.jpg" class="block"> + </div> + <h1 class="font-extrabold text-3xl">Title</h1> + <p class="font-semibold text-xl">Subtitle</p> + </header> + <article class="text-md leading-loose prose"> + <div id="post-content"> + <!-- ... --> + </div> + <div id="post-endnotes"> + <ul> + <!-- ... --> + </ul> + </div> + <div id="author-info" class="bg-white px-4 py-6 my-2 shadow"> + <p>Author Name</p> + <p>Description</p> + <a href="https://mastodon.social/@author">Mastodon</a> + </div> + </article> + <footer> + <!-- ... --> + </footer> +</main> +``` + +偶尔还能见到一些莫名其妙的 HTML 结构,比如我就见过这样的: + +```HTML +<div id="scroll-body"> + <div id="contant-wrap-wrap"> + <div id="content-wrap"> + <div id="main-content"> + <div id="page-content"></div> + </div> + </div> + </div> +</div> +``` + +~~简直有大病。~~ 无论如何,尽管它们的结构不同,但包含的内容是相似的,换句话说,**数据结构**是相似的。他们都有可能是一篇文章,包含页面标题、内容、作者信息等等,这篇内容同时还有可能是另一篇内容的回应、点赞或转发。 + +被浏览器渲染为图形过后,人读起来会理所应当地觉得这些就是相同的数据,但在机器看来就难了。HTML 结构有无限种可能,要怎么让机器快速且准确地判断某个网页属于什么类型的内容,它包含了哪些结构化的数据? + +其实已经有一些方案被提出了,比如被广泛使用的 [Open Graph 协议](https://ogp.me/)。网页只要按照标准,添加一些 `<meta>` 标签,就可以使其成为一个数据对象。Facebook 等社交媒体,在遇到这些链接的时候,会爬取 Open Graph 的内容,生成更具视觉效果的卡片。 + +以下是 Open Graph 的一个例子: + +```HTML +<meta property="og:title" content="The Rock" /> +<meta property="og:type" content="video.movie" /> +<meta property="og:url" content="https://www.imdb.com/title/tt0117500/" /> +<meta property="og:image" content="https://ia.media-imdb.com/images/rock.jpg" /> +``` + +microformats 是类似的东西,但他没有规定新的 `<meta>` 标签类型,也不像另一个标准 [JSON-LD](https://www.w3.org/TR/json-ld11/) 一样要求插入一大段包含 JSON 的 `<script>` 标签。它就建立在最基础的 HTML 之上。 + +以下是用 microformats 标记的一篇博客文章示例。 + +```HTML +<article class="h-entry"> + <h1 class="p-name">Microformats are amazing</h1> + <p>Published by <a class="p-author h-card" href="http://example.com">W. Developer</a> + on <time class="dt-published" datetime="2013-06-13 12:00:00">13<sup>th</sup> June 2013</time></p> + + <p class="p-summary">In which I extoll the virtues of using microformats.</p> + + <div class="e-content"> + <p>Blah blah blah</p> + </div> +</article> +``` + +注意到 `class` 的值了吗?`p-name` 标记了这篇博客文章的名字,`p-author` 标记了作者,`p-summary` 标记了这篇文章的总结摘要,`e-content` 则是这篇文章的内容。最外层的 `h-entry`,标记这是一个条目,博客文章、社交媒体发帖和维基页面等等,都可以用这个类名标记。 + +要实现 microformats 标准,你不需要在其他地方添加任何别的格式的数据,只需要在原有的 HTML 上操作就好了。刚刚我们看到的是 [h-entry](https://microformats.org/wiki/h-entry) 格式,用来标记发布在万维网上的内容,除此之外,还有用来标记人和组织的 [h-card](https://microformats.org/wiki/h-card),用来标记日历和事件的 [h-event](https://microformats.org/wiki/h-event) 等等。 + +我们刚才用来配置 IndieAuth 的 `<link rel="me">` 标签,也是一个 [microformats 格式](https://microformats.org/wiki/rel-me)。它更常见的用法是直接标记在 `<a>` 标签上: + +```HTML +<a href="https://github.com/tantek" rel="me">@t</a> +<a href="https://tantek.com/" rel="me">https://tantek.com/</a> +``` + +`rel="me"` 本身不是用来配置 IndieAuth 的,只是标记网站站长的其他网页链接的一种方式。IndieAuth 只是使用了 microformats 的这个格式而已。 + +总而言之,`microformats` 是名副其实的「微格式」,不需要对网站结构做出太大改动,就可以标记结构化的数据。 + +### 和 Webmention 的关系 + +我猜测除了 [webmention.io](https://webmention.io/) 之外,没有太多接收端实现了解析 microformats 的能力(不过,[Weepinbell](https://codeberg.org/eltrac/weepinbell) 可以!)。最初 Webmention 仅仅是「A 网页提及了 B 网页」的通知,并没有什么复杂的分类,但 microformats 的使用让一切都不简单了起来。 + +一般来说,相互提及的网页都是博客文章,文章是用 microformats 的 `h-entry` 标记的。这个格式除了标记基本的元信息之外,还有这样的属性: + +- `u-in-reply-to`:这个 `h-entry` 回复了哪篇文章 +- `p-rsvp`:这个 `h-entry` 是对什么的 RSVP,即表明自己是否要参与某次聚会、活动或事件 +- `u-like-of`:这个 `h-entry` 是对哪篇文章的喜欢(点赞) +- `u-repost-of`:这个 `h-entry` 是对哪篇文章的转发 + +比如,Bob 回应了 Alice 的文章,它在文档开头提及了 Alice 的文章,它可能是这样写的: + +```HTML +<div class="h-entry"> + <h1 class="p-name">对 Alice 文章的回复</h1> + <div class="e-content"> + <p>前几天我在 Alice 的博客上读到了 + <a class="u-in-reply-to" href="https://alice.blog/"> + 一篇有趣的文章 + </a>, + 我很受启发。</p> + <p>对这个问题,我也有相似的思考。</p> + <!-- ... --> + </div> +</div> +``` + +你注意到了吗?Bob 把文章中提及的链接标记为 `u-in-reply-to`。如此一来,这篇文章在能够解析 microformats 的程序看来,就是对 Alice 文章的一篇回应。如果是 `u-like-of`,就是对那篇文章的点赞,`u-repost-of` 就是转发。 + +至于 `p-rsvp`,我觉得这个设计有点大病——真的会有人写网页公开发 RSVP 吗?这种东西难道不应该私下交流吗?无论如何,它是存在的,你可以用 microformats 标记 RSVP,也意味着你可以用 Webmention 来发 RSVP 通知他人你是否决定出席某次活动。 + +具体而言,Webmention 和 microformats 这两个标准是这样一起使用的:支持解析 microformats 的 Webmention 接收端,在收到请求时,除了做最基本的检查之外,还会解析 `source` 网页中的 microformats,如果有的话,就一起保存下来。 + +IndieWeb 上的居民会根据 `h-entry` 是否包含 `u-in-reply-to` 等属性,决定展示 Webmention 的方式。如果有 `u-in-reply-to`,就显示为回复或评论;如果有 `u-like-of`,就显示为点赞;如果有 `u-repost-of`,就显示为转发。以下是 Barnaby Walters 的网站实现这一展示方式的例子。 + +") + +如果都没有,那就当作普通的提及,也就是最原始的 Webmention。 + +### 在 Webmention 中显示自己的名字和头像 + +上一小节解释了 `h-entry` 格式,用来标记内容。用来标记作者时,可以用到 `h-card` 格式。 + +```HTML +<a class="h-card" href="https://tantek.com/">Tantek Çelik</a>, + +<span class="h-card"> + <a class="p-name p-org u-url" href="https://microformats.org/">microformats.org</a> +</span> +``` + +`h-card` 本来是独立的,用来标记人和组织的格式,但它也可以作为 `h-entry` 的子属性 `p-author`,放在 `h-entry` 里,标记这个内容的作者。 + +```HTML +<div class="h-entry"> + <div class="p-author h-card"> + <img src="https://aaronpk.com/images/aaronpk.jpg" class="u-photo" width="40"> + <a href="https://aaronpk.com/" class="u-url p-name">Aaron Parecki</a> + </div> +</div> +``` + +这样,其他软件在解析 microformats 的时候,就能发现你的名字和头像了。一般来说也会展示在 Webmention 里。 + ## 同步来自联邦宇宙的提及 +你可能怀疑会不会真的有人这样用 microformats,给链接标记 `u-in-reply-to` 这样的类名总归有点麻烦,大部分时候我们只是简单提及一篇文章而已,不见得就是对那篇文章的直接回应,或者说点赞和转发。这些东西更像是社交媒体上会用到的。 + +嗯?社交媒体? + +既然我们在讨论开放的标准,那就不得不提及开放且去中心化的社交媒体了。是的,我说的就是[联邦宇宙](https://jointhefediverse.net/?lang=zh-hans)。有没有办法把来自联邦宇宙的点赞、回复和转发,以 Webmention 的方式同步到网站上呢? + +答案是使用 [Brid.gy](https://brid.gy/),这个服务允许你用 Mastodon 账号(以及其他兼容 Mastodon API 的联邦宇宙软件)登录,并将社交媒体账号与你的网站桥接起来。它做的事情很简单: + +1. 每隔一段时间扫描你的社交媒体时间线,以及其他人与你的互动。 +2. 如果发现你的某篇帖文包含你的网站上的 URL,而又有人点赞、回复或转发了这篇帖文,那么就视作这个人点赞、回复或转发了你网站上对应的这篇文章。 +3. 创建一个占位 HTML 页面,包含用 microformats 标记的 `h-entry`,以这个占位页面作为 `source`,给你网站上的页面发送 Webmention。(如果你直接访问这个占位页面,会被跳转到实际的联邦宇宙帖子,但 Webmention 接收器会把这个占位页面视作真实的 `source` 地址) + +如此一来,你的网站就通过 Webmention 和联邦宇宙互通了。 + +我的网站就是这样做的,拉到页面最下方,你就能看到来自联邦宇宙的点赞和回应,不过我还没想好应该如何展示「转发」这个类型的 Webmention。 + ## 自己动手写 Webmention 接收端 |
