把页面链接贴到 LinkedIn / X / Slack / Telegram / WhatsApp / 微信,预览卡片要么完全没图、要么显示一张早就改掉的旧图。
最快修复(覆盖约 70% 的情况):用 LinkedIn 的 Post Inspector 或 Facebook 的 Sharing Debugger 打开你的页面,看它抓到的 og:image 值,确认两件事。(1) 它是不是以 https:// 开头的绝对 URL,而不是 /?(2) 爬虫是否真的把图片抓到了(没报错、有真实预览)?如果是相对路径,改成绝对 URL 再重爬;如果值正确但预览是旧图,点 Scrape Again 清缓存。
OG 协议的失败模式集中在三类:meta 标签写错(几乎都是相对路径)、图片本身不符合某个平台的要求(尺寸 / 格式 / 大小),或者平台返回的是好几天前缓存的爬取结果。本文按命中率排出 5 类原因,并给一条从 debugger 抓包到强制重爬的修复路径。下文所有限制均为 2026 年 6 月时点数据。
常见原因
按命中率从高到低。
1. og:image 用了相对路径
OG 爬虫不会做相对路径解析——它直接拿 content 里的字符串当 URL 请求。<meta property="og:image" content="/og.png"> 在浏览器里能渲染,爬虫却拿到 /og.png 这种没法 fetch 的字符串。
<!-- 错:相对路径,社交爬虫拿不到 -->
<meta property="og:image" content="/og/article-slug.png" />
<!-- 对:必须是绝对 URL,含 protocol -->
<meta property="og:image" content="https://yourdomain.com/og/article-slug.png" />
如何判断:用 LinkedIn Post Inspector / Facebook Sharing Debugger / opengraph.dev 输入你的 URL,看 og:image 字段值是不是 / 开头而不是 https://。
2. 图片尺寸 / 比例不符合各平台要求
各平台有最小尺寸硬限制和宽高比目标。低于绝对下限的图片会被丢弃;介于下限和推荐尺寸之间,通常会拿到一张小缩略图或被裁切的卡片,而不是大图卡。下表为 2026 年 6 月时点数据:
| 平台 | 推荐尺寸 | 绝对最小 | 宽高比 |
|---|---|---|---|
| Facebook / LinkedIn | 1200×630 | 200×200(Facebook);LinkedIn 对宽度低于约 1200 的会降级成小缩略图 | 1.91:1 |
Twitter / X (summary_large_image) | 1200×628 | 300×157 | 约 1.91:1 |
| Slack | 1200×630 | 600×600 | 不限严格 |
| 1200×630 | 100×100(低于此值完全不出预览图) | 1.91:1 | |
| 微信 | 任意,但偏好 5:4 | 300×300 | — |
唯一在所有平台都通用的尺寸是 1200×630、比例 1.91:1。Facebook 技术上能渲染到 200×200,但要拿到大图卡(而不是靠左的小缩略图)至少要 600×315,要在高 DPI 屏上清晰则需要 1200×630。
如何判断:debugger 报错 Image size is too small、预览里只显示标题加描述没有图,或者出现一张方形小缩略图而不是宽幅横图。
3. 社交平台缓存了旧爬取
平台会缓存爬取结果,避免每次分享都重新抓。2026 年 6 月时点:LinkedIn 缓存约 7 天,Facebook 会一直保留上一次的爬取直到你强制刷新,X 则在 URL 被重新提交到 validator 时重新读取。你已经更新了 og:image,但分享出来还是旧图,就是因为缓存还没过期。
有一个 LinkedIn 的坑要先知道:在 Post Inspector 里重爬只会更新之后新发帖子的预览。已经包含这条链接的旧帖子仍然用老卡片。所以正确顺序是:先改标签,再重爬,然后重新发一条——编辑旧帖子是没用的。
如何判断:debugger 里看到 “Last scraped: 5 days ago” 或类似时间戳;一个全新 URL 第一次分享就正常,而一个更新过的 URL 还在显示旧图。
4. 图片 URL 需要登录 / 加了 CORS 限制
og:image 指向了一个需要 cookie / token / referrer 的 CDN(比如 Cloudinary 的 signed URL),或者 origin 加了 Access-Control-Allow-Origin 白名单、不包含社交爬虫 UA。
如何判断:
curl -A "facebookexternalhit/1.1" -I "https://yourdomain.com/og/article.png"
# 期望 200 + image/png;返回 403 / 401 / 重定向到登录页就是被挡了
5. 文件格式 / 大小超出限制
老老实实用 PNG 或 JPEG。GIF / SVG / WebP 在各家爬虫里支持度参差(尤其 SVG 几乎都被拒,动图 GIF 会被取某一帧、常常很丑)。文件大小方面,Facebook 文档里的硬上限是 8MB,LinkedIn / X 在 5MB 左右,但实际天花板低得多:爬虫在慢源站上远没到 8MB 就超时了,所以目标控制在 300KB 以内,把 1MB 当上限。
ls -lh og.png # 目标 < 300KB;超过约 1MB 就有概率被爬虫超时丢弃
file og.png # 期望:PNG image data 或 JPEG image data
如何判断:debugger 报 Unsupported image format 或 Image too large;或者第 3 步在浏览器里能拉到图,但爬虫显示没图。
最短修复路径
先用官方 debugger 看爬虫究竟拿到了什么,再针对性修。
Step 1:用各平台官方 debugger 抓一次爬取
| 平台 | URL |
|---|---|
https://developers.facebook.com/tools/debug/ | |
https://www.linkedin.com/post-inspector/ | |
| Twitter / X | 旧的 cards-dev.twitter.com/validator 从 2022 年起就不再显示预览,只能用日志确认 X 是否能读到卡片。要看真实预览,把 URL 贴进 X Tweet Composer,或用 opengraph.dev 这类第三方工具 |
| Telegram | 在和 @WebpageBot 私聊里直接发 URL |
把 URL 粘进去,看:
og:image是不是绝对 URL(以https://开头)- 抓到的图片预览是否正确
- 有没有报错文案(Facebook 显示在 “Warnings That Should Be Fixed” 下面,LinkedIn 直接行内显示)
Step 2:检查 meta 标签是否齐全且为绝对 URL
最小有效配置:
<meta property="og:title" content="文章标题" />
<meta property="og:description" content="一句话摘要" />
<meta property="og:image" content="https://yourdomain.com/og/article.png" />
<meta property="og:image:width" content="1200" />
<meta property="og:image:height" content="630" />
<meta property="og:image:alt" content="几个词描述这张图" />
<meta property="og:url" content="https://yourdomain.com/articles/article-slug/" />
<meta property="og:type" content="article" />
<meta name="twitter:card" content="summary_large_image" />
<meta name="twitter:image" content="https://yourdomain.com/og/article.png" />
有两个细节能悄悄解决”第一次分享就没图”:og:image:width 和 og:image:height 不是可选项。一个全新 URL 被分享时,爬虫还没抓到图片,得靠这两个声明的尺寸来判断要不要渲染大图卡。填对(1200 和 630),第一次分享就出横幅;不填,第一次分享往往要等之后重爬才有图。
Step 3:验证图片本身可被爬虫 fetch
# 用社交爬虫的 User-Agent 拉一次
curl -A "facebookexternalhit/1.1 (+http://www.facebook.com/externalhit_uatext.php)" \
-I "https://yourdomain.com/og/article.png"
# 期望响应:
# HTTP/2 200
# content-type: image/png
# content-length: 理想 < 1000000 (1MB)
返回 403 / 401 / 302 都说明被认证或权限挡了。把这条路径设为公开:在 CDN 白名单里加上爬虫 UA,或把图片放到 public 静态目录、让前面没有任何鉴权层。需要放行的主要爬虫 UA 是 facebookexternalhit、LinkedInBot、Twitterbot、Slackbot-LinkExpanding 和 WhatsApp。顺便确认页面的 SSL 证书有效——LinkedInBot 等爬虫遇到证书错误会直接放弃并返回空预览。
Step 4:让社交平台强制重新抓取
每个 debugger 都能强制重新爬一次:
- Facebook Debugger:粘 URL → “Debug” → “Scrape Again”。如果还是旧图,再点一次;Facebook 经常要爬两遍缓存才更新。
- LinkedIn Post Inspector:粘 URL → “Inspect” 自动重新抓取(缓存约 7 天)。记住:这只会修好重爬之后分享的帖子,已经发出去的帖子不受影响。
- Twitter / X:把 URL 重新提交到
cards-dev.twitter.com/validator,强制 X 重新读取页面(那里已经不显示预览了),然后把 URL 贴进 Tweet Composer 看刷新后的卡片。 - Telegram:和
@WebpageBot私聊发 URL,在回复里点 “refresh”。
如果是大量页面要批量刷新,写脚本调用 Facebook Graph API 的 ?scrape=true:
curl -X POST "https://graph.facebook.com/?id=https://yourdomain.com/articles/foo&scrape=true&access_token=$FB_TOKEN"
Step 5:图片不合格时按规格重新导出
按 1200×630 PNG 或 JPEG 导出,文件大小控制在 300KB–1MB:
# ImageMagick 一键转换
convert input.png -resize 1200x630^ -gravity center -extent 1200x630 -quality 85 og.png
# 或 sharp (Node.js)
npx sharp-cli -i input.png -o og.png resize 1200 630 --fit cover
不要用 SVG(很多平台不支持)和 GIF(动图会被取首帧,常常很丑)。
如何确认已经修好
别只信一个平台。按顺序跑这三个检查:
- 爬虫能拉到图:重跑第 3 步的
curl -A "facebookexternalhit/1.1" -I,确认HTTP/2 200加content-type: image/png(或image/jpeg)。 - debugger 预览正确:在 Facebook Sharing Debugger 和 LinkedIn Post Inspector 里重爬,确认宽幅横图渲染出来、
og:image显示为完整https://URL、且没有 warning。 - 真实分享:把链接发到一个私密渠道(给自己发的 Slack DM、X Composer 里的草稿推文、一条测试 LinkedIn 帖子),肉眼确认大图卡。这是唯一能反映读者实际看到效果的测试。
如果 curl 返回 200、debugger 预览也正确,但真实分享还是错的,那几乎一定是那个平台上的缓存问题(原因 3)——在该平台重爬,然后发一条新帖子。
预防建议
- OG 图片统一用 1200×630 PNG/JPG,文件控制在 300KB 以内(1MB 硬上限);不要用 SVG / GIF / WebP。
- 用一个 helper 函数把
og:image/og:url强制转成绝对 URL,避免每篇文章手写出错。 - 始终输出
og:image:width、og:image:height、og:image:alt,让新 URL 的第一次分享就能渲染大图卡。 - 在 CI 里跑一个 og-check 脚本:
curl -A facebookexternalhit ...拉每个新文章的og:image,校验 200 加正确 content-type。 - 新发布文章后立刻在 Facebook / LinkedIn debugger 触发一次 scrape,避免被缓存挡住前几天的分享。
- 用一个生成器(
@vercel/og、satori、puppeteer)自动按标题生成 OG 图,杜绝”忘了配图”。
常见问答
为什么我的 OG 图在 Slack 能显示,LinkedIn 却不行? 缓存不同、最小尺寸要求也不同。Slack 对链接展开很积极、对小图也容忍;LinkedIn 缓存约 7 天,对宽度低于约 1200px 的图会降级成小缩略图甚至丢掉。在 Post Inspector 里重爬,并确认图片至少 1200×630。
我换了图,但分享出来还是旧图,怎么强制刷新? 平台缓存了上一次的爬取。在 Facebook Sharing Debugger 里点 “Scrape Again”(有时要点两次),并在 LinkedIn Post Inspector 里重爬。对 LinkedIn 来说,刷新只对新帖子生效,所以重爬后要重新发一条,而不是编辑原帖。
Twitter / X 现在还有 card validator 吗?
cards-dev.twitter.com/validator 这个页面还在,但从 2022 年起就不再显示预览了,只能用日志确认 X 是否能读到你的卡片。要看真实卡片,把 URL 贴进 Tweet Composer,或者用 opengraph.dev 这类第三方工具。
我的 og:image 在浏览器里返回 200,爬虫却显示没图,为什么?
浏览器会带上你的 cookie 和正常的 user-agent,爬虫不会。图片很可能在鉴权、signed-URL、referrer 校验或基于 UA 的 CORS/防火墙规则后面。用 -A "facebookexternalhit/1.1" 重跑 curl——如果拿到 403/401/302,就在 CDN 白名单放行爬虫 UA,或把图片挪到公开的静态路径。
有没有一个尺寸在所有平台都通用? 1200×630 像素,比例 1.91:1,PNG 或 JPEG,300KB 以内。它能同时满足 Facebook、LinkedIn、X、Slack 和 WhatsApp,不用为每个平台做不同版本。