掌握Open Graph协议让网页分享更出彩
先上代码,我每次都这么写
每次做新项目,只要涉及到社交分享,第一件事就是把 Open Graph 标签给加上。不是为了多高级的功能,就是为了避免别人转发你链接的时候,封面图裂了、标题乱码、描述变成页面第一段文字——太丢人了。
我现在用的这套 meta 写法,已经在我所有项目里复制粘贴了快两年,亲测在微信、QQ、微博、Telegram、Discord 上都正常显示。直接贴出来,你照着抄就行:
<meta property="og:title" content="你文章的标题" />
<meta property="og:description" content="一段简洁有力的描述,别超过 200 字" />
<meta property="og:image" content="https://jztheme.com/images/cover.jpg" />
<meta property="og:url" content="https://jztheme.com/article/123" />
<meta property="og:type" content="article" />
<meta property="og:site_name" content="站点名称" />
<meta name="twitter:card" content="summary_large_image" />
<meta name="twitter:image" content="https://jztheme.com/images/cover.jpg" />
这里有几个细节要说明:
- og:image 最好是绝对路径,相对路径在很多平台不认,尤其是移动端 QQ 和微信
- 图片尺寸建议 1200×630 像素,这是 Facebook 官方推荐的,兼容性最好
- content 里的内容不要带换行或引号,不然解析会出问题,我之前因为 description 里有个双引号,整个卡片不显示,折腾了半天才发现
- og:type 可以是 article、website、video 等,如果是博客文章就用 article,首页用 website 就行
动态生成?别慌,我给你个通用方案
上面是静态写法,但大多数项目都是动态的,比如 React、Vue 或者 PHP 模板。这时候就得根据当前页面数据动态注入 meta 标签。
以 Vue + Vue Router 为例,我是这么做的:
// router.js 或 main.js 里监听路由变化
router.afterEach((to) => {
const { title, description, image } = to.meta;
// 动态设置 og:title
updateMeta('og:title', title);
updateMeta('og:description', description);
updateMeta('og:image', image);
updateMeta('og:url', window.location.href);
// 同时更新 Twitter 卡片
updateMeta('twitter:title', title);
updateMeta('twitter:description', description);
updateMeta('twitter:image', image);
});
function updateMeta(property, content) {
if (!content) return;
let meta = document.querySelector(meta[property="${property}"]);
if (!meta) {
meta = document.createElement('meta');
meta.setAttribute('property', property);
document.head.appendChild(meta);
}
meta.content = content;
}
然后在每个页面的路由 meta 里写清楚:
{
path: '/article/123',
component: ArticlePage,
meta: {
title: '前端如何优雅地处理滚动穿透',
description: '本文记录我在开发弹窗组件时踩过的三个大坑',
image: 'https://jztheme.com/images/scroll-bug.jpg'
}
}
这样切换页面的时候,meta 标签就会自动更新。注意:必须是在页面加载完成后执行,否则可能被 SSR 或 CDN 缓存影响。
踩坑提醒:这三点一定注意
下面这些是我一个个试出来的血泪经验,你现在看到的是结果,背后我被产品骂了三回。
1. 图片必须能被外网访问,且不能有防盗链
曾经我把 og:image 指向了一个本地 Nginx 的地址:http://localhost:8080/cover.jpg,本地测试没问题。一上线,微信分享直接不显示图片。为什么?因为微信的服务器没法访问你本机。
还有一次用了云存储,但没关 Referer 防盗链,导致 Telegram 抓取失败。解决方案很简单:确保图片可以通过公网直接访问,并且 HTTP Header 不限制 Referer。
2. 内容缓存了?强制刷新试试
微信对 OG 标签的缓存非常狠。哪怕你改了 meta,用微信打开还是旧的。解决办法只有一个:换 URL。
或者用这个 trick:
<meta property="og:url" content="https://jztheme.com/article/123?v=2" />
加个版本参数,骗过微信缓存。别笑,生产环境真这么干。
3. 特殊字符转义,别偷懒
如果你的标题是 “前端人,困在 35 岁?” 这种,一定要记得把 ? 转成 HTML 实体,或者用 JS 设置时自动 escape:
content = content.replace(/?/g, '&?');
或者更稳妥的做法是,在模板引擎里统一做过滤。PHP 用 htmlspecialchars,JS 用 encodeURIComponent(仅限拼接时),Vue 用 v-text 自动转义。
SSR 场景下怎么搞?别让爬虫抓空
如果你用 Next.js、Nuxt.js 或者自研 SSR,千万别在客户端再塞 meta 标签。等你 JS 执行完,爬虫早就走了。
正确做法是在服务端渲染阶段就把 OG 数据注入进去。以 Express + EJS 为例:
app.get('/article/:id', async (req, res) => {
const article = await getArticle(req.params.id);
res.render('article', {
title: article.title,
description: article.summary,
image: article.coverImage,
url: https://jztheme.com/article/${req.params.id}
});
});
然后在 ejs 模板里:
<meta property="og:title" content="<%= title %>" />
<meta property="og:description" content="<%= description %>" />
<meta property="og:image" content="<%= image %>" />
<meta property="og:url" content="<%= url %>" />
这样返回的 HTML 源码里就已经带了完整 OG 信息,搜索引擎和爬虫都能直接抓到。
高级技巧:根据不同平台微调
你以为 OG 标签全平台通用?错。Twitter 就不太买账。
Twitter 主要用自己的 twitter:* 标签。虽然它也支持 og,但为了保险起见,建议同时写两套:
<meta property="og:title" content="通用标题" />
<meta name="twitter:title" content="专为 Twitter 优化的标题" />
<meta property="og:description" content="通用描述" />
<meta name="twitter:description" content="Twitter 专用描述,可以更短一点" />
<meta property="og:image" content="https://jztheme.com/image.jpg" />
<meta name="twitter:image" content="https://jztheme.com/image-twitter.jpg" />
<meta name="twitter:card" content="summary_large_image" />
你会发现 Twitter 更喜欢 summary_large_image,而默认的 summary 显示的图很小。想大图就一定要加这个。
另外,twitter:card 的取值有几种:
summary:小图模式summary_large_image:大图模式(推荐)app:应用推广player:音视频嵌入
一般博客用 summary_large_image 就够了。
调试工具:别靠猜,用实测
改完之后别自己瞎试,用官方工具看解析结果。
推荐三个:
- Facebook Sharing Debugger:
https://developers.facebook.com/tools/debug/—— 输入 URL,看它抓到了啥 - Twitter Card Validator:
https://cards-dev.twitter.com/validator—— 测试 Twitter 卡片效果 - WhatsApp Link Preview Tester:发给自己就能看预览
特别提醒:Facebook 工具可以强制重新抓取,相当于刷新缓存。比你改十次代码都管用。
最后一点:SEO 和 OG 别混为一谈
有人问我:“加了 OG 是不是 SEO 就好了?” 不是。OG 是为了让社交分享好看,不影响搜索引擎排名。
SEO 主要看 <title>、meta[name="description"]、结构化数据这些。OG 是锦上添花,不是雪中送炭。
不过话说回来,如果分享出去的卡片难看,没人点,流量上不去,SEO 再好也没用。所以该做还得做。
以上是我个人对 Open Graph 的实战总结,有更优的实现方式欢迎评论区交流。这个技巧的拓展用法还有很多,比如结合 PWA、动态生成海报图、多语言适配等,后续会继续分享这类博客。

暂无评论