埋め込みコンテンツは、他のページやサイトのコンテンツを共有しながら、ユーザーをサイトに留めておくための最適な方法です。たとえば、Twitter のスタイルと形式で表示される埋め込みツイートなど、小さなものもあります。たとえば、Shopify ショップを埋め込んで、サイトを離れることなく購入できるようにするなど、完全に独立したサイトを埋め込むこともできます。
コンテンツを埋め込む際にサイトの安全性を維持することが、これまで以上に重要になっています。
デベロッパーがウェブサイトにコンテンツを埋め込む方法はいくつかあります。最も一般的な手法は <iframe>
を使用することです。これにより、URL だけでサイトにコンテンツを埋め込むことができます。sandbox
属性を追加して iframe のセキュリティを強化することはすでに可能です。
または、提案されている HTML 要素を使用することもできます。
<fencedframe>
は、プライバシーを保護しながらサードパーティのコンテンツを埋め込む方法として提案されています。<portal>
は、よりシームレスなページ遷移のために提案されています。
埋め込みコンテンツのセキュリティを強化する方法について、以下で説明します。
iframe を使用して埋め込む
iframe は、お問い合わせページに地図やフォームを追加したり、広告を表示したりするなど、さまざまなユースケースで使用できます。
<iframe src="https://example.com/maps"></iframe>
各 iframe には独自のブラウジング コンテキストがあり、独自のセッション履歴とドキュメントがあります。iframe を埋め込むコンテキストは、親ブラウジング コンテキストと呼ばれます。
iframe に表示されるサードパーティ コンテンツは、postMessage()
を介して親サイトとやり取りできます。これにより、デベロッパーはブラウジング コンテキスト間で任意の値を送信できます。メッセージ レシーバは、イベント リスナー onmessage
を使用して値を受け取ることができます。
// inside iframe
window.parent.postMessage("ping", "https://example.com");
// window
window.addEventListener("message", (event) => {
console.log(event.data);
})
sandbox
属性によるセキュリティの強化
悪意のあるコンテンツが iframe にデプロイされている場合、意図しないアクション(JavaScript の実行やフォームの送信など)が実行される可能性があります。これを回避するため、sandbox
属性は iframe 内の実行可能 API を制限し、有害な可能性のある機能を無効にします。
<iframe src="https://example.com" sandbox></iframe>
サンドボックスでは、埋め込みコンテンツにとって重要な特定の API が使用できなくなる場合があります。無効な API を許可するには、サンドボックス属性に引数を明示的に追加します。
<iframe sandbox="allow-forms" src="https://example.com"></iframe>
sandbox
仕様には、allow-forms
、allow-same-origin
、allow-popups
など、さまざまな値が考えられます。
権限に関するポリシー
ウェブ向けにますます強力な機能が開発されるにつれて、それらすべての権限を管理するために権限ポリシーが作成されました。権限ポリシーは、親サイトと iframe コンテンツに適用できます。親サイトに付与された権限は、allow
属性を使用して iframe に付与することもできます。
<iframe src="https://example.com" allow="fullscreen"></iframe>
フェンス付きフレームで埋め込む
フェンス付きフレーム(<fencedframe>
)は iframe と同様に、埋め込みコンテンツ用に提案された HTML 要素です。iframe とは異なり、フェンス付きフレームは埋め込みコンテキストとの通信を制限し、埋め込みコンテキストと共有することなく、フレームがクロスサイト データにアクセスできるようにします。同様に、親ページのファースト パーティ データはフェンス付きフレームと共有できません。
<fencedframe src="https://3rd.party.example"></fencedframe>
Fenced Frames は、トップレベル サイトがデータをパーティション分割することを提案するプライバシー サンドボックスの提案です。プライバシー サンドボックスの提案の多くは、サードパーティの Cookie や他のトラッキング メカニズムを使用せずに、複数のサイトにまたがるユースケースに対応することを目的としています。一部のプライバシー サンドボックス API では、特定のドキュメントをフェンス付きフレーム内でレンダリングする必要があります。
たとえば、FLEDGE API 広告オークションの落札者に対してフェンス付きフレームが作成されます。FLEDGE API は、フェンス付きフレーム内でレンダリングできる、位置に依存しない URN スキームである不透明なソースを提供します。不透明なソースを使用すると、サイト運営者は広告ソースの URL を知ることなく、サイトにコンテンツを表示できます。
<fencedframe src="urn:uuid:c36973b5-e5d9-de59-e4c4-364f137b3c7a"></fencedframe>
最終的に、フェンス付きフレームは iframe に置き換わることはありません。これらを使用する必要はありません。フェンス付きフレームは、異なるトップレベル パーティションのデータを同じページに表示する必要がある場合に使用する、よりプライベートなフレームとして提案されています。
ポータルに埋め込む
ポータル(<portal>
)は、独立したブラウジング コンテキストを持つ HTML 要素の提案であり、ページの切り替えエクスペリエンスを改善する可能性があります。ポータルは iframe などのコンテンツを埋め込みますが、ユーザーはポータルのコードにアクセスできません。ポータルは閲覧専用であり、ユーザーが操作することはできません。
ポータルは、マルチページ アプリケーションの複雑さを軽減し、シングルページ アプリケーションのシームレスな移行を実現します。これらのトランジションはアニメーション化でき、ブラウザ ウィンドウのコンテンツをすばやく置き換えることができます。
<portal src="https://example.com/"></portal>
ポータルの仕様はまだ開発の初期段階です。
埋め込みに使用されるその他の HTML 要素
ウェブの歴史の中で、コンテンツを埋め込むために提案された HTML 要素や作成された API が数多く存在します。しばらくの間、複数の <frame>
要素と 1 つの <frameset>
要素でサイトを作成するのが一般的でした。複数の <frameset>
要素を含むサイトでは、個々のフレームのソースに関係なく、親ページの URL がアドレスバーに表示されます。これにより、サイト内のコンテンツへのリンクを共有することが困難になりました。これらの API はその後非推奨になりました。
また、Java の <applet>
要素などのプラグイン テクノロジーを使用して、他のユースケースをカバーしていた時期もありました。これは後に <object>
要素に置き換えられました。これらの要素はどちらも、Flash プラグインの表示によく使用されていましたが、他の HTML 要素の表示にも使用されていました(iframe と同様)。<canvas>
、<audio>
、<video>
、<svg>
などの他の要素により、<object>
要素と <applet>
要素の両方が廃止されました。
<object>
と <embed>
はまだ正式に非推奨になっていませんが、特に奇妙な動作をするため、使用しないことをおすすめします。<applet>
は 2017 年に HTML 仕様から削除されました。
まとめ
既存の iframe 仕様を使用して、コンテンツを任意のウェブサイトに安全に埋め込むことができます。セキュリティとスタイルの改善のために、<fencedframe>
や <portal>
などの HTML 要素が提案されています。フェンス付きフレームの提案については、進捗状況を随時お知らせします。