Chankay Blog
演示文章
English简体中文
演示文章
Chankay Blog
GitHubBilibili

© 2026 Chankay Blog

使用无头浏览器截图生成 OG 图片

2026年4月10日•阅读 3 分钟

为什么 Open Graph 图片对社交分享很重要、传统方案如何生成它们,以及本站如何结合无头浏览器截图与异步队列,自动产出像素级还原的 OG 图片。

分享链接时会发生什么?

当你把一个 URL 粘贴到 Twitter、Slack 或任何即时通讯应用中时,平台会获取目标页面的 HTML,并查找 Open Graph 元标签:

如果没有 og:image,分享出去的链接就只是一个普通 URL。有了它,链接会变成包含标题、描述和视觉预览的丰富卡片。

有 OG 图片 → 点击率更高,用户一眼就能获取更多信息。

没有 OG 图片 → 链接很容易被直接划过。

生成 OG 图片的传统方式

方式 工作原理 优点 缺点
手动设计 为每个页面从 Figma/Photoshop 导出图片 质量高 难以扩展——每个页面都需要手动处理
Canvas API 在服务端通过 node-canvas 合成图片 可自动化 布局能力弱、不支持 CSS,调试痛苦
@vercel/og(Satori) 将 JSX 转换为 SVG,再转为 PNG 与 Next.js 集成良好,可在 Edge 环境运行 只支持 CSS 的一部分,复杂布局能力有限
无头浏览器 在真实浏览器中渲染页面并截图 完整支持 CSS/JS,所见即所得且像素级还原 需要浏览器运行时,资源成本更高

前三种方式都在尝试模拟浏览器的渲染,而第四种方式则是直接使用浏览器本身。

本站的方案:无头浏览器截图

本站使用无头浏览器截图,但并不直接管理 Chromium 实例,而是把截图任务交给一个无头浏览器云 API。

完整的生成流程

从编辑者保存页面,到 OG 图片准备就绪,完整流程如下:

状态机

每个页面的 OG 图片生成状态遵循一个简单的有限状态机:

关键设计决策

为什么不在 Hook 中直接截图?

Hook 运行在 CMS 的请求—响应周期内,而一次截图需要 5–10 秒。如果让保存操作等待这么久,编辑体验会非常糟糕。因此 Hook 只负责标记状态和分发任务,真正的截图在异步流程中完成。

为什么需要专用的预览路由?

OG 图片需要特定的视觉布局:没有导航栏和页脚,并针对 1200×630 的宽高比进行优化。预览路由只渲染页面的内容区块,不包含网站外壳,同时通过身份验证请求头保护,避免被公开访问。

为什么 Processor 在截图前要重新加载页面?

队列任务可能会延迟执行。任务从分发到真正执行之间,编辑者可能已经继续修改了内容。重新从数据库读取页面,可以确保截图反映的是最新内容。

不同环境如何切换队列?

Dispatcher 会自动检测运行环境。在生产环境中,它使用支持重试和指数退避的云队列服务;在开发环境中,则使用内存中的 Promise Map 直接执行,无需额外的外部基础设施。

On this page

  • 分享链接时会发生什么?
  • 生成 OG 图片的传统方式
  • 本站的方案:无头浏览器截图
  • 完整的生成流程
  • 状态机
  • 关键设计决策