OG 图片在社交分享时不显示:3 个原因 + 修复路径

分享到 LinkedIn / X / Slack 没图——meta 标签 / 尺寸 / 缓存。

把页面链接贴到 LinkedIn / X / Slack / Telegram / 微信,预览卡片要么完全没图、要么显示一张早就改过的旧图——OG 协议的失败模式集中在三类:meta 标签写错(特别是相对路径)、图片本身不合规(尺寸 / 格式 / 大小),或者社交平台缓存了 24 小时前的爬取结果。本文按命中率排出 5 类原因,并给一条从 debugger 抓包到强制重爬的修复路径。

常见原因

按命中率从高到低。

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 / Twitter Card Validator / Facebook Sharing Debugger 输入你的 URL,看 og:image 字段值是不是 /xxx 开头。

2. 图片尺寸 / 比例不符合各平台要求

各平台有最小尺寸和宽高比硬限制,不达标直接不展示:

平台推荐尺寸最小比例容忍
Facebook / LinkedIn1200×630600×3151.91:1
Twitter / X (summary_large_image)1200×628300×1572:1
Slack1200×630600×600不限严格
微信任意,但偏好 5:4300×300

低于 600px 宽几乎所有平台都会拒绝展示。

如何判断:debugger 报错 Image size is too small 或预览里只显示标题不显示图。

3. 社交平台缓存了旧爬取

LinkedIn / Facebook / Twitter 抓取一次后会缓存 7 天到 30 天。你已经更新 og:image 但分享出来还是老图。

如何判断: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. 文件格式 / 大小超出限制

GIF / SVG / WebP 部分平台不支持;单图文件大小超 5MB(Facebook 上限 8MB、LinkedIn 5MB、Twitter 5MB)会被丢弃。

ls -lh og.png   # 期望 < 1MB;超过 3MB 就有概率被拒
file og.png     # 期望 PNG image data 或 JPEG image data

如何判断:debugger 报 Unsupported image formatImage too large

最短修复路径

先用官方 debugger 看爬虫究竟拿到了什么,再针对性修。

Step 1:用各平台官方 debugger 抓一次爬取

平台URL
Facebookhttps://developers.facebook.com/tools/debug/
LinkedInhttps://www.linkedin.com/post-inspector/
Twitter / X旧 Card Validator 已下线,用 https://opengraph.dev 替代
Telegram在和 @WebpageBot 私聊里直接发 URL

把 URL 粘进去,看:

  1. og:image 字段是不是绝对 URL
  2. 抓到的图片预览是否正确
  3. 报错文案(如果有)

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: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" />

Astro / Next.js 项目里用一个 helper 强制拼绝对 URL:

// src/lib/og.ts
const SITE = import.meta.env.PUBLIC_SITE_URL ?? "https://yourdomain.com";
export const absoluteOg = (path: string) =>
  path.startsWith("http") ? path : `${SITE}${path.startsWith("/") ? "" : "/"}${path}`;

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: < 5000000

返回 403 / 401 / 302 都说明被认证或权限挡了,需要把这条路径设为公开(CDN 白名单加上爬虫 UA,或把图片放到 public 静态目录)。

Step 4:让社交平台强制重新抓取

每个 debugger 都有”Scrape again” / “Re-scrape” / “Refresh” 按钮:

  • Facebook Debugger:粘 URL → “Debug” → “Scrape Again”
  • LinkedIn Post Inspector:粘 URL → 自动重新抓取(缓存约 7 天)
  • Twitter (opengraph.dev):粘 URL → “Refresh”
  • 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(动图会被取首帧,常常很丑)。

预防建议

  • OG 图片统一用 1200×630 PNG/JPG,文件控制在 1MB 以内;不要用 SVG / GIF / WebP。
  • 用一个 helper 函数把 og:image / og:url 强制转成绝对 URL,避免每篇文章手写出错。
  • 部署后在 CI 里跑一个 og-check 脚本:curl -A facebookexternalhit ... 拉每个新文章的 og:image,校验 200 + 正确 content-type。
  • 新发布文章后立刻在 Facebook / LinkedIn debugger 触发一次 scrape,避免被默认 30 天缓存挡住前几天的分享。
  • 用一个生成器(@vercel/og、satori、puppeteer)自动按标题生成 OG 图,杜绝”忘了配图”。

相关阅读

标签: #部署 / 托管 #排查 #排查 #SEO