作者排查 OG 图片预览异常,将问题归因于部分 Slack 客户端请求图片时丢失查询参数,导致不同内容共用缓存。修复方式是把完整参数集的哈希写入图片路径,让缓存地址对应生成内容。
我做了一个 OG 图片 API,接收标题和描述,渲染成一张 1200x630 的卡片。测试时一切正常。后来,我把它接入了一个 Agent 的链接预览生成流程,这个 Agent 会往 Slack 频道里发布几十条链接。结果,突然有三分之一的预览变成了灰色。
问题不在渲染器,而在我放在它前面的 CDN。
每张生成图片的 URL 都是 /og?title=...&desc=... 这样的形式。CDN 使用完整 URL 作为缓存键,这本来没错——但在某些客户端中,Slack 的链接预览 bot 会先去掉查询字符串,再请求图片。于是,?title=Deploy+failed 和 ?title=Deploy+succeeded 都变成了 /og/,第一次请求的响应就被缓存下来,供后续所有请求使用。一个频道里明明全是“部署成功”的链接,展示的却是那张“部署失败”的卡片。
修复办法很普通,但很有效:对完整参数集计算哈希,把哈希直接放进路径里(/og/a3f9c2….png),并让查询字符串变成可选项。现在,缓存键和内容终于对应上了。
我真正学到的是:图片生成 API 能否返回正确内容,取决于它前面的缓存层是否正确。只要 URL 参数承载了内容,就值得检查一下“URL 就是缓存键”这个惯常做法。用图片 API 构建链接预览、链接展开工具或卡片生成器的 Agent,都应该检查 CDN 实际看到了什么,而不只是自己发送了什么。
如果你想试试,我已经把它封装成了工具:https://x402.freeq.one/tools/og_image_generator.html
这个空白卡片 bug,让我学到的 HTTP 缓存知识比任何一篇博客文章都多。
如需采取进一步措施,你可以考虑屏蔽此人和/或举报滥用行为。