はてなブログカードと oEmbed API

はてなブログの記事作成で、リンクボタンからリンクを挿入したり、サイドバーの「過去記事貼り付け」で記事を貼り付けたりしますとブログカードが作成されます。


www.imuza.com

これですね。このブログカード内のリンクが自サイトであっても別ウィンドウ(タブ)で開くのを同じウィンドウにしようとして、それ用にサーバーまで立てようかということになっています(笑)。

で、いろいろやっている際にブログカードをちゃんと理解していないことに今更ながら気づきました。



hatenablog-parts.comとは?

ブログカードというのはてっきりメタタグの OGPデータを取ってくるものだと思っていたのですが、必ずしもそうではなく、oEmbedという仕様を実装しているサイトからは oEmbedを使い、そうでないサイトからは OGPデータを使うようです。


ですので、ブログカードのソースコード iframeの src属性として設定される URL https://hatenablog-parts.com/embed は、おそらく内部で、ターゲットとなるサイトが oEmbedを実装しているかどうかをチェックし、実装されていれば oEmbedで、されていなければ OGPデータでブログカード用の HTMLを返しているのではないかと思われます。


これ、はてなの開発ブログを時系列で読めばすぐに分かることでした。


staff.hatenablog.com


はてなブログoEmbed API

はてなブログの oEmbedの仕様はこちらのページにあります。

developer.hatena.ne.jp


oEmbedの利用の仕方を整理するとこういうことかと思います。

  • そのサイトが oEmbedを実装しているかどうかは head内の link要素で示す
    たとえば、このページの冒頭のブログカードでは次のようになっています。
<link rel="alternate" type="application/json+oembed" href="https://hatenablog.com/oembed?url=https%3A%2F%2Fwww.imuza.com%2Fentry%2F2019%2F02%2F04%2F194914&amp;format=json" title="oEmbed Profile of node.js で URLパースすると favicon.ico が返る"/>
<link rel="alternate" type="text/xml+oembed" href="https://hatenablog.com/oembed?url=https%3A%2F%2Fwww.imuza.com%2Fentry%2F2019%2F02%2F04%2F194914&amp;format=xml" title="oEmbed Profile of node.js で URLパースすると favicon.ico が返る"/>
  • oEmbedのエンドポイントは、https://hatenablog.com/oembed
  • 参照したいページのパーマリンクを URLクエリとして渡す
  • 返されるデータフォーマットは json または xml

ということで、link要素の href属性に整形された URLが入っています。


実際に https://hatenablog.com/oembed?url=https%3A%2F%2Fwww.imuza.com%2Fentry%2F2019%2F02%2F04%2F194914&amp;format=json にアクセスし jsonデータを取得してみますと、

{ author_url: 'https://blog.hatena.ne.jp/ausnichts/',
  url: 'https://www.imuza.com/entry/2019/02/04/194914',
  published: '2019-02-04 19:49:14',
  height: '190',
  width: '100%',
  provider_name: 'Hatena Blog',
  image_url:
   'https://cdn-ak.f.st-hatena.com/images/fotolife/a/ausnichts/20190204/20190204195536.jpg',
  author_name: 'ausnichts',
  description:
   'はてなのブログカードはたとえ自サイトであっても別ウィンドウ(タブ)で開いてしまい ますので、それを同じウィンドウで開くようにしようと思っているのですが、DOM操作ではうまくいかず、じゃあ、サーバーを立ち上げて、呼ばれたら指定のサイトから OGPデータを取得し てブログカード用にコーディングして返せばいいんじゃないかということで試してみようと思 います。 node.js でサーバーを立ち上げる URL をパースする node.js でサーバーを立ち上げる ググればいっぱいヒットします。簡単ですね。 const http = require(\'http\'); const server = http.cr…',
  blog_title: 'IMUZA.com',
  type: 'rich',
  categories: [ 'Node.js', 'javascript' ],
  blog_url: 'https://www.imuza.com/',
  title: 'node.js で URLパースすると favicon.ico が返る',
  version: '1.0',
  provider_url: 'https://hatenablog.com',
  html:
   '<iframe src="https://hatenablog-parts.com/embed?url=https%3A%2F%2Fwww.imuza.com%2Fentry%2F2019%2F02%2F04%2F194914" title="node.js で URLパースすると favicon.ico が返 る - IMUZA.com" class="embed-card embed-blogcard" scrolling="no" frameborder="0" style="display: block; width: 100%; height: 190px; max-width: 500px; margin: 10px 0px;"></iframe>' }

が返ってきます。変数 htmlには iframeのコードが入っています。エディタはこれを読んでいるということでしょう。


oEmbedを実装していないサイトのブログカード

oEmbedを実装していないサイト、たとえば、MDNの iframeのページをブログカードにしてみますと

developer.mozilla.org

とほぼ同じようなブログカードになります。iframeの src属性も同じく hatenablog-parts.com/embed です。


staff.hatenablog.com

こちらの記事にありますように OGPデータを利用しているようです。OGPデータをもっていないサイトはどうなるかは、上にあります「はてなブログoEmbed API」のブログカードのようにリンクだけになるようです。


ということで、自サイトに限ってのブログカード用のサーバーを立ち上げるのなら oEmbedを利用したほうがいいようです。