Skip to content
This page has been auto-translated and may contain errors.View in English

埋め込みと iframe

docs.scrimba.com

あなたが望むコンテンツがすでに別の場所に存在することがあります。YouTube の動画、地図上の位置、別の企業が運営する支払いフォーム。それを再構築する代わりに、その全体ページをあなたのページの中に配置することができます。これを行う要素が <iframe> で、サイズ調整、アクセシビリティ、セキュリティを保つための一連の制御が付いています。

iframe 要素

iframe は別のウェブページをあなたのページの中に配置します。名前は「inline frame」の略で、それはそれをよく表しています。小さなフレーム付きウィンドウがあなたのページに있고, 完全に独立したページがそこに見えています。ブログ投稿にある YouTube 動画はほぼ常に iframe です。

src 属性を使って表示したいページを指定します。これは画像がそのファイルに使う属性と同じです。

html
<iframe src="https://www.youtube.com/embed/aqz-KE-bpKQ"></iframe>

この単一のタグが YouTube プレーヤーをあなたのページに引き込みます。壁に窓を掛けるのをイメージしてください。壁はあなたのページで、その窓を通して全く別の部屋が見えます。

<iframe> は別の完全なウェブページをロードして、それをあなたのページの中の長方形として表示します。src 属性にそのページのアドレスを持ち、フレーム内のすべて、独自の HTML、CSS、JavaScript はそれ自体で実行され、あなたのページから分離されています。

html
<iframe src="https://www.openstreetmap.org/export/embed.html"></iframe>

開始タグと終了タグの間に書いたものは何でもフォールバックコンテンツです。これは iframe をサポートするには古すぎるブラウザにのみ表示されます。実際にはそのようなブラウザはほぼ存在しません。フレームは完全にその属性を通じて設定され、次のセクションで実際に設定するものについて説明します。

<iframe>ネストされた閲覧コンテキスト を作成します。あなたのドキュメント内に埋め込まれた完全で独立したドキュメント(閲覧コンテキストは単一ページが実行される環境で、独自の履歴、独自のグローバルスコープ、DOM の独自のコピーを持ちます)。フレームはあなたのページの DOM ツリーの一部ではなく、あなたのページ上のボックスの中に描画される別のページです。

その分離がまさにポイントで、同一オリジンポリシー によって強制されます。あなたのページとフレーム内のページは、同じオリジン(オリジンはスキーム、ホスト、ポートの組み合わせです。つまり https://example.comhttps://other.com は異なるオリジン)を共有する場合にのみ、互いを読み取るかスクリプト化することができます。同じオリジンのフレームは JavaScript を通じて iframe.contentWindow でアクセスすることができます。異なるオリジンのフレームは、指すことはできますがインスペクトできない密閉されたボックスです。配置するほぼすべての埋め込み、動画、地図、ウィジェットはクロスオリジンです。これはちょうど安全に配置できる理由です。

Junoiframe 要素<iframe> は別のウェブページ全体をあなたのページの中に表示します。別の部屋を見ているような小さなウィンドウのように。src で指す先を指定します。画像と同じ方法で。ブログ上の YouTube プレーヤー?ほぼ常にこれの 1 つです。
Junoiframe 要素<iframe> は別の自己完結型ページをロードして、あなたのページ上のボックスに表示します。独自の HTML、CSS、JavaScript はあなたのページから壁で分離されたままです。属性を通じて完全に設定します。src から始まります。
Junoiframe 要素 フレームはネストされた閲覧コンテキストです。独自のスコープと DOM を持つ完全に別のドキュメントで、あなたのドキュメントの分岐ではありません。同一オリジンポリシーがそれをシールしているので、クロスオリジンの埋め込みは表示されることができますがあなたのページによってスクリプト化されることはできません。その壁は制限ではなく、機能です。

動画、地図、ウィジェットの埋め込み

良いニュース。埋め込みコードを手で書くことはほぼありません。埋め込み元のサイトがあなたのために書きます。YouTube で Share をクリックしてから Embed をクリックすると、コピーする準備ができた <iframe> をくれます。地図、音楽プレーヤー、カレンダーもすべて同じように機能します。それらのブロックをコピーして HTML に貼り付けます。

html
<iframe src="https://www.youtube.com/embed/aqz-KE-bpKQ" width="560" height="315"></iframe>

widthheight はフレームのサイズを設定し、ピクセルで測定されます。これら 2 つの数字を変更すると、動画はあなたのページ上でより大きくまたはより小さくなります。

ほとんどの埋め込みコードは直接ソースから来ます。Share または Embed ボタンを探すと、サービスはあなたのために調整され指示された <iframe> ブロックをくれます。3 つの属性は単にペーストするのではなく理解する価値があります。

html
<iframe
  src="https://www.youtube.com/embed/aqz-KE-bpKQ"
  width="560"
  height="315"
  title="Big Buck Bunny 短編映画"
  loading="lazy"
></iframe>

widthheight はフレームのサイズをピクセルで設定します。title 属性は スクリーンリーダー のためにフレームに名前を付けます。これはリンクのテキストを発表する方法でそれを発表するので、タイトルのないフレームはラベルのない「フレーム」として読まれ、誰にも役に立ちません。loading="lazy" はブラウザにリーダーがそれの近くにスクロールするまで、フレーム内のページのダウンロードを保留するよう指示し、ページ下部の埋め込みが初期ロードを遅くするのを防ぎます。

固定ピクセルサイズの代わりにコンテナに合わせて拡張すべきフレームの場合、widthheight 属性を削除して CSS でサイズ調整します。aspect-ratio を使用して動画の比率を正しく保ちます。

サービスがあなたに提供する埋め込みスニペットは妥当なデフォルトで、完成した決定ではありません。いくつかの属性が本番環境でそれがどの程度良く動作するかを決定します。

html
<iframe
  src="https://www.youtube-nocookie.com/embed/aqz-KE-bpKQ"
  title="Big Buck Bunny 短編映画"
  loading="lazy"
  referrerpolicy="strict-origin-when-cross-origin"
  allowfullscreen
  style="width: 100%; aspect-ratio: 16 / 9; border: 0;"
></iframe>

title は実際のところ必須です。支援技術(ページを音声で読み上げるスクリーンリーダーなどのソフトウェア)はフレームを ランドマーク として扱い、そのタイトルを発表するので、欠落しているものは読み取り順序に空白の領域を残します。loading="lazy" はフレームのドキュメントロードを、それがビューポート(ページの表示エリア)に近づくまで延期します。ここで重要なのはなぜなら各フレームは完全なページロードで、単一のアセットではないからです。referrerpolicy はページの URL のどのくらいが Referer ヘッダー(ブラウザがリクエストがどこから来たかをサーバーに伝えるために添付するフィールド)で埋め込みサービスに送られるかを制御し、それを厳しくするとあなたのユーザーについてのリーク情報が減ります。小さい画面でフレームが リフロー できるように、固定ピクセルではなく aspect-ratio で応答的にサイズ調整します。保つ価値がある習慣は 1 つです。ペーストする前にスニペットを読むこと。プロバイダーが選んだデフォルトを継承しているからです。

Juno動画、地図、ウィジェットの埋め込み 埋め込みコードをあなた自身で書くことはほぼありません。YouTube、地図、またはプレーヤーで Share または Embed ボタンを探して、貼り付ける <iframe> をくれます。widthheight を変更してサイズを変更します。そのほとんどがこの仕事です。
Juno動画、地図、ウィジェットの埋め込み ソースから埋め込みコードを取得してから、それをきれいにしてください。スクリーンリーダーがフレームに名前を付けることができるように常に title を追加し、ページ下部のフレームが最初のペイントを遅くしないように loading="lazy" を追加します。柔軟なサイズ調整については、ピクセルの幅と高さを削除して CSS の aspect-ratio を使用します。
Juno動画、地図、ウィジェットの埋め込み プロバイダーのスニペットは出発点です。title は読み取り順序のため、loading="lazy" はフレームが 1 つのアセットではなく完全なページロードであるため、厳密な referrerpolicy はあなたのユーザーについてのリーク情報を減らすため、そして aspect-ratio は応答的なサイズ調整のため。ペーストするものを読んでください。あなたが選んだすべてのデフォルトを継承しているからです。

サンドボックスとパーミッション

フレームは別のページ全体を実行するため、そのページが何をすることが許可されているかを制限したいかもしれません。sandbox 属性はまさにそれを行います。安全なフェンスの後ろにフレームを配置します。

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

sandbox をそれ自体で使用して、フレーム内のページは最も厳しい設定に保たれます。独自のスクリプトを実行したり、フォームを送信したり、新しいウィンドウをポップオープンしたりすることはできません。その後、特定のパーミッションを 1 つずつ渡します。埋め込みが実際に必要なものだけです。誰かに部屋を貸すことをイメージしてください。ただし、開きたくないキャビネットはロックしたままです。

2 つの属性がフレームが何をすることが許可されているかを制御します。sandbox はフレームを制限し、allow はデバイスとブラウザ機能へのアクセスを付与します。

値なしで sandbox を追加すると、フレーム内のページができることのほぼすべてをブロックします。スクリプト、フォーム、ポップアップ、そして同一オリジンとしての扱い。スペース区切りのパーミッショントークンをリストして緩和できます。

html
<iframe
  src="https://example.com/widget"
  sandbox="allow-scripts allow-forms"
></iframe>

allow-scripts はフレームに JavaScript を実行させ、allow-forms はそれにフォームを送信させ、allow-popups はそれに新しいウィンドウを開かせます。埋め込みが必要なもののみを付与してください。独立した allow 属性は全画面表示、カメラ、マイクなどの機密ブラウザ機能を管理します。

html
<iframe src="https://example.com/call" allow="camera; microphone; fullscreen"></iframe>

機能が allow にリストされていない場合、フレーム内のページはそれを使用できません。その独自のコードが要求している場合でも。

2 つの異なるモデルがここにあり、それらを分離しておく価値があります。sandbox はフレームから機能を削除し、allow はゲートされた機能へのアクセスを付与します。これらは同じ事の 2 つのスペルではありません。

値なしの sandbox はすべての制限を一度に適用します。スクリプトなし、フォーム送信なし、ポップアップなし、自動再生メディアなし、そして重要なこととして、フレームはユニークな 不透明オリジン に強制されます(他のものと一致しないオリジン。そのため、フレームは誰でもと同一オリジンであることを主張することができません。ロード元のサイトを含めて)。トークンで機能を戻します。

html
<iframe
  src="https://example.com/widget"
  sandbox="allow-scripts allow-popups allow-popups-to-escape-sandbox"
></iframe>

避ける価値がある組み合わせが 1 つあります。allow-scriptsallow-same-origin を両方とも、あなた自身のオリジンからロードされるフレームに付与すると、フレーム内のページが独自のサンドボックスを削除するために戻ってアクセスできるコードを実行できます。これはポイントを台無しにします。これら 2 つをペアにするのは、フレームのコンテンツが完全に信頼されている場合のみです。

allow 属性は パーミッションズポリシー です(カメラ、マイク、ジオロケーション、全画面表示などの機密機能を使用できるページを決定するためのブラウザメカニズム)。デフォルトは拒否です。allow で名前が付けられていない機能は、スクリプトがリクエストしているもの関わらずフレームで利用できません。これはカメラを必要とするビデオコール ウィジェットを配置でき、ページ上の他のすべてのフレームにもそのカメラを渡さない方法です。

Junoサンドボックスとパーミッション フレームに sandbox を追加すると、埋め込みページをロックダウンします。スクリプトなし、ポップアップなし、ゴタゴタなし。その後、実際に必要なパーミッションのみを渡します。部屋を貸すようなもので、いくつかのキャビネットはロックしたままです。
Junoサンドボックスとパーミッションsandbox はフレームを制限し、allow-scriptsallow-forms のようなトークン毎に緩和します。独立した allow 属性はカメラ、マイク、または全画面表示を付与するものです。それぞれに埋め込みが実際に求めるもののみを与えてください。
Junoサンドボックスとパーミッション 2 つのモデルを区別してください。sandbox は機能を奪い取り、allow はゲートされた機能を付与し、デフォルトは拒否です。トラップは allow-scriptsallow-same-origin と同一オリジンのフレーム上でペアリングすることで、ページが独自のサンドボックスをアンロックさせるからです。中身を完全に信頼する場合のみそれを実施してください。

セキュリティとパフォーマンスの注意

埋め込みは便利ですが、各フレームは全体の追加ページをロードするため、それらのスタックはあなたのページを遅く感じさせることができます。2 つの習慣があなたを トラブル から守ります。信頼できるサイトからのみ埋め込み(それらのページをあなたのページに招待しているため)、あなたが必要以上に多くのフレームを追加しないこと。

前に述べた loading="lazy" 属性もここで役に立ち、フレームをリーダーがそれにスクロールするまで保留します。埋め込みが本当の作業を節約する場合(動画や地図など)にそれに手を伸ばし、plain リンクが同じ仕事をする場合はスキップしてください。

追加する全フレームは完全なページロードです。独自の HTML、独自の CSS、そして多くの場合、独自の JavaScript のパイル。すべて別のサーバーからフェッチされます。3 つのサードパーティ埋め込みを持つページは実際には 4 つのページが一度にロードされます。これが埋め込み重いページが重く感じられる理由です。オフスクリーンフレーム上の loading="lazy" は最も安い勝利で、3 つの埋め込みより 1 つを好むことが次のものです。

スピード以上の第 2 の懸念があります。誰かのフレーム内に配置されるのからあなた自身のページを保護することができます。これは攻撃者があなたのサイトをフレーム化し、ユーザーを見えないクリックをするように欺くトリックを阻止します。その保護はサーバーで設定され、高度なレベルではそれを行う 2 つのヘッダーを説明します。

2 つのコストは明確なまなざしに値します。フレームがあなたのパフォーマンスに何をするか、そしてフレーミングがあなたのセキュリティに何ができるか。

パフォーマンス上、サードパーティ フレームは単一のリクエストではなく、プロバイダーの完全なスタックを実行する ネストされたドキュメントロード です(それらのマークアップ、スタイル、フォント、分析、スクリプト)あなたのページの内部。同じネットワークとメインスレッド競争し、スクリプトはそれ自体のコンテキストで実行されますが同じデバイスで、重い埋め込みはあなた自身のコンテンツがインタラクティブになるのを遅延させることができます。loading="lazy" はオフスクリーンフレームを延期し、埋め込みを統合することはいずれかの 1 つをチューニングしていることを倒します。実際のコストを計測してから埋め込みが無料であると仮定してください。

セキュリティ上、リスクは クリックジャッキング です。攻撃者があなたのページを彼らのサイト上のフレームにロード、それを見えなくするか覆う、そしてサイン イン ユーザーをあなたのページ上の実際のコントロールをクリックするように誘う。それを実現せずに。防御は誰がいるのか宣言することです。もしいれば、あなたのページをフレーム化することができ、それはあなたのサーバーで HTML ではなくレスポンスヘッダーで設定されます。

  • X-Frame-Options: DENY はあなたのページがどのフレームでもロードされるのを拒否します。SAMEORIGIN はあなた自身のサイトがそれをフレーム化することのみ許可します。これは古い、より粗い制御です。
  • Content-Security-Policy: frame-ancestors 'self' は現代的な置き換えです。frame-ancestors はあなたのページをフレーム化することができるオリジンを正確にリストします(Content-Security-Policy または CSP はヘッダーで、ブラウザにどのコンテンツとビヘイビアソースを許可するかを指示します)。X-Frame-Options に取って代わり、 1 つのブランケットルールではなく特定の許可リストを許可し、ログインまたはフォームを持つ何かで設定するのは 1 つです。

方向に注意してください。sandboxallow はあなたが埋め込むページを制御し、frame-ancestorsX-Frame-Options はあなたを埋め込む人を制御します。両方の方向が重要で、異なる場所で設定されます。

Junoセキュリティとパフォーマンスの注意 すべてのフレームは全体の追加ページをロードするため、それらの山はあなたのページを遅くします。信頼できるサイトからのみ埋め込み、カウントを低く保ち、loading="lazy" に頼ります。plain リンクが同じ仕事をするであれば、リンクを使用してください。
Junoセキュリティとパフォーマンスの注意 3 つの埋め込みは 4 つのページが一度にロードされることを意味します。そのため、各フレームを実際のコストとして扱ってください。loading="lazy" はオフスクリーンフレームは安い勝利で、より少ない埋め込みは 1 つをチューニングしていることを倒します。深い遊びで覆う 2 つのサーバーヘッダーで有効です。フレーミングリスクも保護する価値があります。
Junoセキュリティとパフォーマンスの注意 サードパーティ フレームはあなたのページ内のプロバイダーの全体スタックを実行し、あなたのネットワークとメインスレッド競争します。そのため、計測してから安いと仮定してください。セキュリティ上、クリックジャッキングを阻止してください。あなたをフレーム化できることを宣言することで。CSP の frame-ancestors は現代的な制御、X-Frame-Options はより古い制御です。方向を忘れないでください。sandbox はあなたが埋め込むページを守り、frame-ancestors はあなたを埋め込む人を守ります。