HTML 入門

HTML <iframe> タグ

<iframe> 要素(インラインフレーム)は、現在のドキュメントの中に別の HTML ドキュメントを埋め込むことができる、HTML における非常に強力なツールです。これは、サードパーティ製コンテンツの埋め込み、広告の表示、あるいはメインページをリロードせずに独立したコンテンツをロードする場合など、多くのシナリオで非常に有用です。

本章では、<iframe> の使用方法、重要な属性、および注意すべきセキュリティ上の考慮事項について詳しく解説します。

1. <iframe> の基本操作

<iframe> 要素はインラインフレームであり、独立したブラウジングコンテキスト(Browsing Context)を作成して、任意の有効な URL コンテンツをロードできます。最もシンプルな使い方は、埋め込みたいウェブページのパスを src 属性に指定することです。

<iframe src="https://www.example.com" width="600" height="400">
  お使いのブラウザは iframe をサポートしていません。
</iframe>

この例では、widthheight 属性でフレームのサイズを定義しています。<iframe> タグの間に記述されたテキストは、iframe をサポートしていないブラウザで表示されるエクリプス降格(Graceful Degradation)メカニズムとして機能します。

2. 主要属性の詳説

<iframe> 要素には、その挙動、外観、およびセキュリティを制御するための複数の属性が用意されています。

2.1 src 属性

src 属性は必須であり、埋め込むドキュメントの URL を指定します。これは相対パス(自サイト内のページ)または絶対パス(他サイトのページ)のいずれかになります。

2.2 width と height 属性

これらの属性は <iframe> の幅と高さを設定するために使用され、ピクセル値またはパーセンテージで指定できます。

<iframe src="page.html" width="100%" height="300px"></iframe>

2.3 title 属性

title 属性は <iframe> に対して説明的なタイトルを提供します。これはアクセシビリティ(Accessibility)において極めて重要で、スクリーンリーダーがこのタイトルを読み上げることで、ユーザーがフレームの内容を理解するのを助けます。

<iframe src="map.html" title="会社所在地を表示するインタラクティブマップ"></iframe>

2.4 name 属性

name 属性は <iframe> に名前を割り当てます。この名前は JavaScript からフレームを参照する場合や、フォーム送信のターゲット(target)として使用されます。

<iframe src="form_results.html" name="resultsFrame"></iframe>
<form action="submit_data.html" target="resultsFrame">
  <input type="submit" value="送信">
</form>

2.5 sandbox 属性

sandbox 属性は、<iframe> における最も重要なセキュリティ属性の一つです。これはフレーム内のコンテンツに対して一連の制限を有効にし、潜在的なセキュリティリスクを低減します。デフォルトでは、sandbox 属性が空の場合、すべての制限が有効になります。

特定の値を指定することで、特定の制限を解除できます:

  • allow-forms: フォームの送信を許可します。
  • allow-modals: モーダルウィンドウ(alert()confirm()prompt() など)の表示を許可します。
  • allow-orientation-lock: 画面の向きのロックを許可します。
  • allow-pointer-lock: Pointer Lock API の使用を許可します。
  • allow-popups: ポップアップ(window.open() など)を許可します。
  • allow-popups-to-escape-sandbox: サンドボックス化されたフレーム内のポップアップがサンドボックス制限を受けないようにします。
  • allow-presentation: Presentation API の使用を許可します。
  • allow-same-origin: フレーム内のコンテンツを親ページと同じオリジンとして扱うことを許可します。これは、フレーム内のスクリプトが親ページの DOM やデータにアクセスするために重要です。この属性がない場合、フレームはユニークなオリジンとして扱われ、同一生成元ポリシー(Same-Origin Policy)による隔離が適用されます。
  • allow-scripts: JavaScript の実行を許可します。
  • allow-storage-access-by-user-activation: ユーザーの操作によってストレージアクセスを要求することを許可します。
  • allow-top-navigation: フレームが最上位のブラウジングコンテキスト(親ページ)を遷移させることを許可します。
  • allow-top-navigation-by-user-activation: ユーザーの操作によって最上位のブラウジングコンテキストを遷移させることを許可します。

sandbox を使用する際、値を何も指定しないと、すべての制限が適用されます。コンテンツはユニークなオリジンと見なされ、スクリプトの実行、フォーム送信、ポップアップの表示などが一切禁止されます。

<iframe src="safe_content.html" sandbox="allow-scripts allow-same-origin"></iframe> 

<iframe src="untrusted_content.html" sandbox=""></iframe>

2.6 allow 属性

allow 属性は、Content Security Policy (CSP) の一部であり、<iframe> 内で使用を許可する特定の機能や API を制御します。これは Feature Policy メカニズムを通じて機能し、親ドキュメントが子フレームに対して特定の機能の使用を明示的に許可します。

一般的な allow の値:

  • accelerometer: 加速度計へのアクセス。
  • autoplay: メディアの自動再生。
  • camera: カメラへのアクセス。
  • geolocation: 位置情報へのアクセス。
  • microphone: マイクへのアクセス。
  • payment: Payment Request API の使用。
  • fullscreen: 全画面モードへの移行。

複数の機能はセミコロン ; で区切って指定できます。

<iframe src="video_player.html" allow="autoplay; fullscreen"></iframe>

2.7 loading 属性

loading 属性は、<iframe> のロードに関するパフォーマンス最適化のヒントを提供します。

  • eager: 直ちに <iframe> をロードします(デフォルト)。
  • lazy: <iframe> がビューポートに近づくまでロードを遅延させます。これにより、ページの初期ロードパフォーマンスが向上します。
<iframe src="lazy_load_map.html" loading="lazy"></iframe>

2.8 referrerpolicy 属性

referrerpolicy 属性は、<iframe> のリクエストを送信する際に Referer HTTP ヘッダーに含める情報を制御します。これはユーザーのプライバシー保護と情報漏洩の防止に役立ちます。

主な値:

  • no-referrer: Referer ヘッダーを送信しません。
  • no-referrer-when-downgrade: HTTPS から HTTP へのリクエスト時には Referer を送信しません。
  • origin: オリジン(プロトコル、ホスト、ポート)のみを送信します。
  • origin-when-cross-origin: クロスオリジンリクエストではオリジンのみを送信し、同一オリジンではフル URL を送信します。
  • same-origin: 同一オリジンリクエストに対してのみ Referer を送信します。
  • strict-origin: HTTPS から HTTPS へのリクエスト時にはオリジンのみ送信し、ダウングレード時には送信しません。
  • strict-origin-when-cross-origin: 同一オリジンではフル URL、クロスオリジン HTTPS 間ではオリジンのみ、ダウングレード時は送信しません。
  • unsafe-url: 常にフル URL を送信します(セキュリティ上の理由から推奨されません)。
<iframe src="external_content.html" referrerpolicy="no-referrer"></iframe>

3. <iframe> のセキュリティ上の考慮事項

<iframe> は任意の外部コンテンツをロードできるため、セキュリティは最も重要な考慮事項です。悪意のあるコンテンツは、クロスサイトスクリプティング(XSS)クリックジャッキング(Clickjacking)、その他の攻撃を試みる可能性があります。

3.1 同一生成元ポリシー (Same-Origin Policy)

ブラウザには同一生成元ポリシーが実装されており、あるオリジンのドキュメントやスクリプトが、別のオリジンのリソースとどのようにインタラクションできるかを制限しています。これにより、異なるドメインの <iframe> は親ページの DOM に直接アクセスしたり操作したりできず、その逆も同様です。これが <iframe> における基本的なセキュリティ隔離となります。

3.2 sandbox 属性

前述の通り、sandbox 属性は <iframe> コンテンツの能力を制限するための推奨メカニズムです。サードパーティ製コンテンツを埋め込む際は常に sandbox 属性の使用を検討し、明確に必要となる機能だけを許可するようにしてください。

3.3 allow 属性 (Feature Policy)

allow 属性は、<iframe> がアクセスできるデバイス機能や API をより細かく制御します。

3.4 Content Security Policy (CSP)

親ページは Content Security Policy を定義して、<iframe>src 属性でロード可能なドメインを制限し、予期せぬ悪意のあるコンテンツのロードを防ぐことができます。

<meta http-equiv="Content-Security-Policy" content="frame-src 'self' example.com bing.com;">

この CSP ルールは、<iframe> が現在のドメイン('self')、example.com、および bing.com からのみコンテンツをロードできるように制限します。

3.5 X-Frame-Options

X-Frame-Options HTTP 応答ヘッダーは、自サイトのページが他サイトの <iframe> 内に埋め込まれるのを防ぎ、クリックジャッキング攻撃を回避するために使用されます。

  • DENY: いかなるサイトのフレーム内でも表示を許可しません。
  • SAMEORIGIN: 同一オリジンのフレーム内でのみ表示を許可します。
  • ALLOW-FROM uri: 指定された URI のフレーム内でのみ表示を許可します(現在は非推奨。CSP の frame-ancestors を推奨)。

注意: 現代の開発では、X-Frame-Options の代替として、より柔軟で強力な CSP の frame-ancestors ディレクティブの使用が推奨されています。

Content-Security-Policy: frame-ancestors 'self' example.com;

これは、現在のオリジンまたは example.com のページだけが、このページを <iframe> 内に埋め込めることを意味します。

4. <iframe> の一般的な用途

  • サードパーティ製動画プレイヤーの埋め込み: YouTube や Vimeo などの動画。
  • 地図の埋め込み: Google Maps など。
  • 広告の表示: 広告コンテンツを隔離し、メインページへの干渉を防ぎます。
  • 非同期コンテンツのロード: メインページをリロードせずに、チャットウィジェットやコメントシステムなどの独立したアプリをロードします。
  • クロスドメイン通信: postMessage() API を通じて、親ページと <iframe> 間の安全な通信を実現します。
  • オンラインエディタ: リッチテキストエディタやコードエディタの埋め込み。

5. レスポンシブ <iframe>

デフォルトでは、<iframe>widthheight 属性は固定されています。異なるデバイスでレスポンシブに対応させるには、通常 CSS を組み合わせる必要があります。

よく使われる手法は、パディング(padding)と position: absolute を利用してアスペクト比を維持する方法です。

<style>
.iframe-container {
  position: relative;
  width: 100%;
  padding-bottom: 56.25%; /* 16:9 の比率 (高さ / 幅 * 100%) */
  height: 0;
  overflow: hidden;
}

.iframe-container iframe {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  border: 0;
}
</style>

<div class="iframe-container">
  <iframe src="https://www.youtube.com/embed/your_video_id" title="YouTube ビデオプレイヤー" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
</div>

padding-bottom56.25%(16:9 の比率に対応)に設定することで、コンテナの高さが幅に応じて自動調整され、その内部に <iframe> が絶対配置で引き伸ばされます。

6. まとめ

<iframe> は、外部コンテンツをウェブページに埋め込むための強力で柔軟な HTML 要素です。しかし、その強力さゆえに、適切なセキュリティ対策が欠かせません。sandboxallow 属性、および Content Security Policy を正しく理解し活用することで、開発者はリスクを最小限に抑えつつ、<iframe> のメリットを最大限に引き出すことができます。実装の際は、常にユーザー体験とセキュリティを最優先に考慮しましょう。