外部サービス埋め込みコンテンツを非同期で読み込む際の注意点とAPI資料まとめ
カイユウ開発部のニンジャです。
今回は、「KAI-YOU.net」をはじめとして日本国内でよく利用されていそうな埋め込みコンテンツについての情報と、おまけで各サービスのAPI情報についてまとめてみたいと思います。
Web媒体の多様なコンテンツ
Web媒体で記事を書く際、記事の構成要素として文字/画像以外にも様々なコンテンツを引用することがあります。
弊社が運営しているメディア「KAI-YOU.net」でも、TwitterやInstagram、Youtube、ニコニコ動画、SoundCloudなどなど、パッと思いつくだけでも様々な外部サービスのコンテンツを引用しています。
通常は、各サービスが提供している「埋め込みコード」と呼ばれる文字列を本文中に差し込むことで、コンテンツを表示します。
埋め込みコード
<iframe width="560" height="315" src="https://www.youtube.com/embed/BCcQpsxLcIo" frameborder="0" allowfullscreen></iframe>
YouTubeの場合、実際に埋め込むと、次のような表示になります。
https://www.youtube.com/watch?v=BCcQpsxLcIo
KAI-YOU.netで引用されている外部サービス
KAI-YOU.netの記事で引用されることが多いコンテンツは以下です。
基本的にはYouTubeの例のような、iframeの埋め込みコードを使うことになるのですが、Twitterとニコニコ動画については少し違ったものが提供されています。
Twitterの場合
New products of KAI-YOU inc, POP is Here.
http://t.co/PkO6u8vDHb pic.twitter.com/qUhIrsiIwa
— KAI-YOU(カイユウ) (@KAI_YOU_ed) 2015, 7月 9
埋め込みコード
<blockquote class="twitter-tweet" lang="ja"><p lang="en" dir="ltr">New products of KAI-YOU inc, POP is Here. <a href="http://t.co/PkO6u8vDHb">http://t.co/PkO6u8vDHb</a> <a href="http://t.co/qUhIrsiIwa">pic.twitter.com/qUhIrsiIwa</a></p>— KAI-YOU(カイユウ) (@KAI_YOU_ed) <a href="https://twitter.com/KAI_YOU_ed/status/619160816512712704">2015, 7月 9</a></blockquote>
<script async src="//platform.twitter.com/widgets.js" charset="utf-8"></script>
widgets.jsの処理が終わると、blockquote部分が削除されてiframeに置き換わる仕組みになっています。
処理後
<iframe id="twitter-widget-0" scrolling="no" frameborder="0" allowtransparency="true" class="twitter-tweet twitter-tweet-rendered" allowfullscreen="" style="border: none; max-width: 100%; min-width: 220px; margin: 10px 0px; padding: 0px; display: block; position: static; visibility: visible; width: 500px;" title="Twitter Tweet" height="181">〜省略〜</iframe>
デフォルトでblockquoteにもiframeにもclass名が付与されるので、あとからいろいろイジる際にもサクっとやりやすくなっています。
widgets.jsには、再構築用の関数が用意されていて、呼び出すと上記の書き換え処理を再実行できます。
Ajaxで読み込む場合は、本文中にtweetが埋め込まれていたら<script async src="//platform.twitter.com/widgets.js" charset="utf-8"></script>
をあらかじめ読み込んでおき、再構築のための関数呼び出しをおこないます。
再構築のための関数呼び出し
twttr.widgets.load();
ニコニコ動画の場合
ニコニコ動画の埋め込みコードは、三種類用意されています。
- 外部プレイヤー
- 動画のサムネイルと詳細情報
- リンクのみ
KAI-YOU.netでよく利用するのは外部プレイヤーの埋め込みです。
「動画のサムネイルと詳細情報」はiframeなので細かいことはあまり気にしなくてよいのですが、埋め込まれたその場で再生できる「外部プレイヤー」の場合がクセモノです。
外部プレイヤーの埋め込みコード
<script type="text/javascript" src="http://ext.nicovideo.jp/thumb_watch/sm22225228?w=490&h=307"></script><noscript><a href="http://www.nicovideo.jp/watch/sm22225228">【ニコニコ動画】【ポケモンXY】第一回 新・厨ポケ狩り講座!【実況】</a></noscript>
この文字列をAjax等で非同期に読み込もうとすると、script部分がごっそりいなくなってしまいます。その際、noscriptにaタグが囲まれているので、ブラウザとしてはscriptを許可しているのに、ニコニコ動画のscriptが読み込めなかったときに何も表示されないという事態になります。
ちなみにですが、以下の様なエラーメッセージが出ます。
Failed to execute 'write' on 'Document': It isn't possible to write into a document from an asynchronously-loaded external script unless it is explicitly opened.
scriptタグのsrcは、動画ごとのID(sm○○○○○○○○)に対応していますが、埋め込みコード自体にclass名もID名も振られていないので、非常に検索しづらいです。動画IDがsmではじまらない場合もあります。
これをAjax等で読み込ませるにはまず、本文中からnoscriptタグを探し、その中のwww.nicovideo.jp という文字列をhref属性を持つaタグを検索して、動画IDを抽出します。その後、http://ext.nicovideo.jp/thumb_watch/○○○○○○○○○○
というsrcを持つエレメントを生成して読み込ませています。(もっと良いやり方があったら教えて下さい;;)
var nocovideoID,
nicovideoSource,
nicovideoScript;
nocovideoID = $('div.hoge noscript a[href*=www.nicovideo.jp]').attr('href').split('/')[4];
nicovideoSource = 'http://ext.nicovideo.jp/thumb_watch/' + nicovideoID;
nicovideoScript = $('<scr'+'ipt>');
nicovideoScript.attr({
'type': 'text/javascript',
'src': nicovideoSource
});
$(".fuga").append(nicovideoScript);
まとめ
埋め込みコードはとても便利なものですが、上で触れたような非同期なページ遷移(Ajaxなど)を実装する場合には、一手間加える必要が生じることもあるという話でした。
その場合は、各Webサービスが公開している開発者向け資料を読みながら、API等を利用することになるのですが、いちいち探すのがけっこう手間だったりするので、最後にまとめておきます。
- Twitter 開発者向け資料
- YouTube 開発者向け資料
- Vimeo 開発者向け資料
- ニコニコ動画 開発者向け資料
- ニコニコ生放送 開発者向け資料
- SoundCloud 開発者向け資料
- Instagram 開発者向け資料
- Vine 開発者向け資料
余談ですが、KAI-YOU.netの記事投稿機能では、URLから埋め込みコンテンツ生成する「oEmbed」という規格を一部利用しています。
こちらの実装の際にもやはり、各Webサービスの開発者向け資料を読み込むことになります。
oEmbedについては、また別記事で触れられればと思います。
カイユウではエンジニア・デザイナーを募集中です!
株式会社カイユウでは、エンジニア・デザイナーを募集しております。
Webにおけるコンテンツ提供の仕組みづくり、魅せ方など、まだまだ発展途上の分野だと思います。
あなたの力で、メディアやコンテンツの未来を明るくしていきましょう!\\\(۶•̀ᴗ•́)۶////