🖼️
フロントエンドで OGP の情報を取得する
OGP
OGP (Open Graph protocol) とはページの情報を外部のサイトへ伝えるための仕組みです。
タイトルやサムネイルの情報を HTML 内の <meta>
タグに記載します。
CORS
外部サイトの OGP 情報を取得しようとしたときにぶつかるのが CORS エラーです。
CORS とはセキュリティの兼ね合いでブラウザーがオリジン(平たく言うとドメイン)をまたいだリクエストのレスポンスに、フロントエンドの JavaScript コードがアクセスすることをブロックする仕組みです。
サーバーは Access-Control-Allow-Origin: *
ヘッダーを付けることでアクセスを許可することもできますが、すべてのサイトがこの設定をしているとは限りません。
詳細は MDN をご参照ください。
CORS Proxy
CORS はブラウザーによる制限なので別のサーバーを経由してアクセスすることで回避することができます。
サーバーで HTML を取得し DOM をパースした結果を返す[1]のが一般的かと思いますが HTML をそのまま返してフロントエンドで DOM をパースすることもできます。
HTML をそのまま返す proxy サーバーを自分でホスト[2]しても良いのですが提供してくれるサービスがあるので今回はこちらを使いましょう。
DOMParser
HTML の取得ができたら後は DOM をパースして OGP の情報を探すだけです。
Node.js だと jsdom を使うようですが Web API には DOMParser が用意されています。
OGP 情報を取得するコード
以上を踏まえて実際に OGP を取得するコードです。
const url = 'https://zenn.dev/';
const proxyUrl = `https://corsproxy.io/?${encodeURIComponent(url)}`;
const response = await fetch(proxyUrl);
const html = await response.text();
const domParser = new DOMParser();
const dom = domParser.parseFromString(html, 'text/html');
const ogp = Object.fromEntries(
[...dom.head.children]
.filter(
(element) =>
element.tagName === 'META' &&
element.getAttribute('property')?.startsWith('og:')
)
.map((element) => {
return [
element.getAttribute('property'),
element.getAttribute('content')
];
})
);
console.log(ogp);
例) Zenn
{
"og:url": "https://zenn.dev",
"og:title": "Zenn|エンジニアのための情報共有コミュニティ",
"og:image": "https://static.zenn.studio/images/logo-only-dark.png",
"og:description": "Zennはエンジニアが技術・開発についての知見をシェアする場所です。本の販売や、読者からのバッジの受付により対価を受け取ることができます。",
"og:type": "article",
"og:site_name": "Zenn"
}
おまけ: Twitter Card
const twitterCard = Object.fromEntries(
[...dom.head.children]
.filter(
(element) =>
element.tagName === 'META' &&
element.getAttribute('name')?.startsWith('twitter:')
)
.map((element) => {
return [
element.getAttribute('name'),
element.getAttribute('content')
];
})
);
console.log(twitterCard);
Discussion
キャッシュや文字コードを考慮したコード例。