--- title: object から iframe へ — その他の埋め込み技術 slug: Learn/HTML/Multimedia_and_embedding/Other_embedding_technologies tags: - Article - Beginner - CodingScripting - Embedding - Flash - Guide - HTML - Learn - Multimedia and embedding - Object - embed - iframe translation_of: Learn/HTML/Multimedia_and_embedding/Other_embedding_technologies ---
そろそろ、画像、動画、音声など、ウェブページへの埋め込みのコツがつかめてきたはずです。ここでは、少し横道にそれて、ウェブページに様々な種類のコンテンツを埋め込むことができる要素、 {{htmlelement("iframe")}}、 {{htmlelement("embed")}}、 {{htmlelement("object")}} を見てみたいと思います。 <iframe>
は他のウェブページを埋め込むためのもので、他の2つの要素は PDF、SVG、 さらに Flash — もうすぐなくなる技術ですが、まだ時々見かけるもの — も、埋め込むことができます。
前提条件: | 基本的なコンピュータリテラシー、インストールされた基本ソフトウェア、ファイルの操作に関する基本知識、HTML の基礎知識 (HTML の入門)、およびこのモジュールの前の記事 |
---|---|
目的: | Flash ムービーなどのウェブページのように、{{htmlelement("object")}}、{{htmlelement("embed")}}、{{htmlelement("iframe")}} を使用してアイテムをウェブページに埋め込む方法を学びます。 |
昔、ウェブ上では、フレームを使ってウェブサイトを作るのが一般的でした - ウェブサイトの小さな部分が個々の HTML ページに保存されていました。これらは、フレームセットと呼ばれるマスター文書に埋め込まれていました。これにより、テーブルの列と行のサイジングのように、各フレームが埋めた画面上の領域を指定することができました。これらは90年代半ばから後半にかけてのクールさの極みと考えられていました。このような小さな塊に分割されたウェブページを持っているとダウンロード速度が向上したという証拠がありました — 特にネットワーク接続が非常に遅いため、特に顕著です。それらは多くの問題を抱えていましたが、ネットワーク速度がより速くなるにつれて、これ以上の利点はなく、あなたはそれらがもう使用されているのを見ていません。
ちょっと後で(90年代後半、2000年代初頭)、{{Glossary("Java","Java アプレット")}}や {{Glossary("Adobe_Flash","Flash")}} などのプラグイン技術が普及しました。これにより、ウェブ開発者は動画やアニメーションなどのウェブページに豊富なコンテンツを埋め込むことができました。これらの技術を埋め込むことは、{{htmlelement("object")}} や、あまり使われていない {{htmlelement("embed")}} などの要素によって実現され、当時は非常に便利でした。アクセシビリティ、セキュリティ、ファイルサイズなど、多くの問題が発生して以来、それらは流行していませんでした。最近のモバイルデバイスのほとんどは、このようなプラグインをサポートしておらず、デスクトップのサポートは出口にあります。
最後に、{{htmlelement("iframe")}} 要素が現れました({{htmlelement("canvas")}}、{{htmlelement("video")}} などのコンテンツを埋め込む他の方法と一緒に)。これは、ウェブ文書全体を別のウェブ文書に埋め込む方法を提供し、あたかも {{htmlelement("img")}} か他の要素であるかのように、今日では普通に使用されています。
歴史の授業を終了して、これらのいくつかの使い方を見てみましょう。
この記事では、能動的学習セクションにまっすぐ飛び込んで、埋め込み技術が有用であるかどうかをすぐに知ることができます。オンラインの世界では Youtube はとてもよく知られていますが、多くの人は利用可能な共有施設については知らないのです。YouTube が {{htmlelement("iframe")}} を使って好きなページに動画を埋め込むことができる仕組みを見てみましょう。
<iframe>
コードがいくつか表示されます。これをコピーします。ボーナスポイントとして、例の中に Google マップを埋め込むこともできます。
<iframe>
コードをいくつか提供します。これをコピーします。間違えた場合は、[Reset] ボタンを使用してリセットすることができます。あなたが本当に立ち往生したら、[Show solution] ボタンを押して回答を見てください。
<h2>Live output</h2> <div class="output" style="min-height: 250px;"> </div> <h2>Editable code</h2> <p class="a11y-label">Press Esc to move focus away from the code area (Tab inserts a tab character).</p> <textarea id="code" class="input" style="width: 95%;min-height: 100px;"> </textarea> <div class="playable-buttons"> <input id="reset" type="button" value="Reset"> <input id="solution" type="button" value="Show solution"> </div>
html { font-family: sans-serif; } h2 { font-size: 16px; } .a11y-label { margin: 0; text-align: right; font-size: 0.7rem; width: 98%; } body { margin: 10px; background: #f5f9fa; }
var textarea = document.getElementById('code'); var reset = document.getElementById('reset'); var solution = document.getElementById('solution'); var output = document.querySelector('.output'); var code = textarea.value; var userEntry = textarea.value; function updateCode() { output.innerHTML = textarea.value; } reset.addEventListener('click', function() { textarea.value = code; userEntry = textarea.value; solutionEntry = htmlSolution; solution.value = 'Show solution'; updateCode(); }); solution.addEventListener('click', function() { if(solution.value === 'Show solution') { textarea.value = solutionEntry; solution.value = 'Hide solution'; } else { textarea.value = userEntry; solution.value = 'Show solution'; } updateCode(); }); var htmlSolution = '<iframe width="420" height="315" src="https://www.youtube.com/embed/QH2-TGUlwu4" frameborder="0" allowfullscreen>\n</iframe>\n\n<iframe src="https://www.google.com/maps/embed?pb=!1m18!1m12!1m3!1d37995.65748333395!2d-2.273568166412784!3d53.473310471916975!2m3!1f0!2f0!3f0!3m2!1i1024!2i768!4f13.1!3m3!1m2!1s0x487bae6c05743d3d%3A0xf82fddd1e49fc0a1!2sThe+Lowry!5e0!3m2!1sen!2suk!4v1518171785211" width="600" height="450" frameborder="0" style="border:0" allowfullscreen>\n</iframe>'; var solutionEntry = htmlSolution; textarea.addEventListener('input', updateCode); window.addEventListener('load', updateCode); // stop tab key tabbing out of textarea and // make it write a tab at the caret position instead textarea.onkeydown = function(e){ if (e.keyCode === 9) { e.preventDefault(); insertAtCaret('\t'); } if (e.keyCode === 27) { textarea.blur(); } }; function insertAtCaret(text) { var scrollPos = textarea.scrollTop; var caretPos = textarea.selectionStart; var front = (textarea.value).substring(0, caretPos); var back = (textarea.value).substring(textarea.selectionEnd, textarea.value.length); textarea.value = front + text + back; caretPos = caretPos + text.length; textarea.selectionStart = caretPos; textarea.selectionEnd = caretPos; textarea.focus(); textarea.scrollTop = scrollPos; } // Update the saved userCode every time the user updates the text area code textarea.onkeyup = function(){ // We only want to save the state when the user code is being shown, // not the solution, so that solution is not saved over the user code if(solution.value === 'Show solution') { userEntry = textarea.value; } else { solutionEntry = textarea.value; } updateCode(); };
{{ EmbedLiveSample('Playable_code', 700, 600, "", "", "hide-codepen-jsfiddle") }}
それは簡単で楽しいものでしたか? {{htmlelement("iframe")}} 要素は、他のウェブ文書を現在の文書に埋め込むことができるように設計されています。これは、直接制御できない可能性のある第三者のコンテンツをウェブサイトに組み込むのに適していて、独自のバージョンを実装する必要はありません — オンライン動画プロバイダの動画、Disqus のようなコメントシステム、オンライン地図プロバイダの地図、広告バナーなど。このコースで使用しているライブ編集可能な例は、<iframe>
を使用して実装されています。
<iframe>
で検討すべき{{anch("Security concerns","セキュリティ上の懸念")}}がいくつかあり、これについては以下で説明しますが、あなたのウェブサイトで使用しないでください — ちょっとした知識と慎重な考えが必要です。コードを少し詳しく見てみましょう。あなたのウェブページの1つに MDN の用語集を含めることを考えていたら、次のようなことを試すことができます。
<iframe src="https://developer.mozilla.org/en-US/docs/Glossary" width="100%" height="500" frameborder="0" allowfullscreen sandbox> <p> <a href="https://developer.mozilla.org/en-US/docs/Glossary"> iframe をサポートしていないブラウザーのための代替リンク </a> </p> </iframe>
この例には、<iframe>
の使用に必要な基本的な要素が含まれています。
<iframe>
は、 Full Screen API を使用してフルスクリーンモードにすることができます(この記事の範囲外です)。: none;
を使用すると、同じ効果がより良く達成できるので、この属性を使用することはもうお勧めできません。<iframe>
と </iframe>
のタグの間に、ブラウザーが <iframe>
をサポートしていない場合に表示される代替コンテンツを含めることができます。この場合、代わりにページへのリンクが含まれています。最近では、<iframe>
をサポートしていないブラウザーを見つけることはまずありません。<iframe>
の機能よりも若干現代的なブラウザー(たとえば、IE 10 以上)で機能し、高度なセキュリティ設定を要求します。これについては、次のセクションで詳しく説明します。メモ: 速度を向上させるためには、メインコンテンツの読み込みが完了した後に iframe の src
属性を JavaScript で設定することをお勧めします。これにより、ページがより早く使用できるようになり、公式ページの読み込み時間が短縮されます(重要な {{glossary("SEO")}} の測定基準)。
上ではセキュリティ上の懸念について言及しました。これについてもう少し詳しく説明しましょう。あなたはこのコンテンツのすべてを初めから完全に理解することを期待していません。この懸念を認識して、より経験豊かになり、あなたの実験や作業で <iframe>
の使用を検討し始める参考にしてください。また、恐怖を感じ、<iframe>
を使わない必要はありません — 注意するだけです。
ブラウザーメーカーやウェブ開発者は、iframe がウェブ上の悪意ある人物(しばしばハッカー、またはより正確にはクラッカーと呼ばれます)の共通のターゲット(公式の用語: 攻撃ベクター)であるということを苦労して学びました。悪意ある人物は、あなたのウェブページを悪意を持って改ざんすることや、ユーザ名やパスワードなどの機密情報を明らかにするなど、人を騙し望んでいないことを行います。このため、仕様技術者とブラウザー開発者は、<iframe>
をより安全にするためのさまざまなセキュリティ・メカニズムを開発しました。また、考慮すべき最善の措置もあります — これらのいくつかを以下で説明します。
{{interwiki('wikipedia','クリックジャッキング')}}は、ハッカーが目に見えない iframe をあなたの文書に埋め込んだり(あなたの文書を自分の悪意のあるウェブサイトに埋め込んだり)して、ユーザの操作を乗っ取るための一般的な iframe 攻撃の一種です。これは、ユーザを誤解させたり機密データを盗む一般的な方法です。
簡単な例ですが、先ほど紹介した例をブラウザーに読み込んでみましょう。Github にライブが公開されています(ソースコードも参照してください)。実際にページに何も表示されませんが、ブラウザーの開発者ツールのコンソールに、理由を示すメッセージが表示されます。Firefox では、"Load denied by X-Frame-Options: https://developer.mozilla.org/en-US/docs/Glossary does not permit framing." (X-Frame-Optionsによって読み込みが拒否されました: https://developer.mozilla.org/en-US/docs/Glossary はフレーミングを許可していません。)というメッセージが表示されます。これは、MDN を作成した開発者が、<iframe>
内に埋め込まれないようにウェブサイトのページを提供する設定をサーバーに組み込んだためです(下記の {{anch("Configure CSP directives","CSP ディレクティブの設定")}}を参照してください)。これは、理にかなっています — あなたのサイトにそれらを埋め込んであなた自身のものと主張するようなことをしない限り、MDN のページ全体が他のページに埋め込まれるのは本当に意味がありません — または、クリックジャッキングを介してデータを盗み出そうとする。どちらも本当に悪いことです。さらに、誰もがこれをやり始めたら、すべての追加の帯域幅が Mozilla に多額の費用をかけるようになります。
場合によっては、第三者のコンテンツを埋め込むことが理にかなっています — youtube 動画や地図のようなものですが、完全に必要なときに第三者のコンテンツだけを埋め込むのであれば、頭を悩ますことはありません。ウェブセキュリティのための良い経験則は、「慎重すぎることは決してありません。もしあなたがそれを作ったら、とにかくそれをもう一度チェックしてください。他の誰かがそれを作ったら、そうでないと証明されるまでそれは危険です。」ということです。
セキュリティのほかに、知的財産の問題にも注意する必要があります。ほとんどのコンテンツは著作権で保護されており、オフラインでもオンラインでも、予期していないコンテンツ(例えば、ウィキメディアコモンズのほとんどの画像)でさえもあります。あなたが所有しているか、または所有者があなたに書面による明白な許可を与えていない限り、ウェブページにコンテンツを表示しないでください。著作権侵害に対する罰則は厳しいものです。繰り返しますが、決して慎重すぎることはありません。
コンテンツにライセンスが付与されている場合は、ライセンス条項に従わなければなりません。たとえば、MDN のコンテンツは CC-BY-SA でライセンスされています。つまり、コンテンツを大幅に変更した場合でも、コンテンツを引用する際には、適切にクレジットを表示する(英語)必要があります。
{{Glossary("HTTPS")}} は {{Glossary("HTTP")}} の暗号化されたバージョンです。可能であれば、HTTPS を使用してウェブサイトを提供する必要があります。
HTTPS を使用するには、高価なセキュリティ証明書が必要です(ただし、Let's Encrypt で簡単にできます) — 入手できない場合は、親文書を HTTP で配信できます。しかし、上記の HTTPS の2つ目の利点のため、コストにかかわらず、第三者のコンテンツを HTTP に埋め込むことは絶対にしないでください(最良の場合のシナリオでは、ユーザのウェブブラウザーは恐ろしい警告を表示します)。<iframe>
を使用してコンテンツを埋め込むことができる評判の良い企業はすべて、HTTPS 経由で利用できるようになります — たとえば、Google マップや YouTube からコンテンツを埋め込む場合は、<iframe>
の src
属性内の URL を調べます。
メモ: Github のページでは、既定で HTTPS 経由でコンテンツを提供できるため、コンテンツのホスティングに便利です。異なるホスティングを使用していて、わからない場合は、ホスティングプロバイダに問い合わせてください。
sandbox
属性を使用する攻撃者には、あなたのウェブサイトで悪いことを行うことができるような力を与えたくないので、埋め込みコンテンツには、その仕事を行うために必要な権限のみを与えるべきです。もちろん、これは自分のコンテンツにも当てはまります。適切に(またはテスト用に)使用できるが、コードベースの残りの部分に何らかの害(偶発的または悪意のある)を及ぼすことができないコード用のコンテナは、サンドボックスと呼ばれます。
サンドボックスにないコンテンツはあまりにも多くのことを行うことができます( JavaScript の実行、フォームの送信、ポップアップウィンドウなど)。既定では、前述の例に示すように、パラメーターなしの sandbox
属性を使用して、使用可能なすべての制限を課す必要があります。
絶対に必要な場合は、権限を1つずつ追加することができます(sandbox=""
属性値内に) — 使用可能なすべてのオプションについては、{{htmlattrxref('sandbox','iframe')}} のリファレンスのエントリを参照してください。重要な注意点の1つは、 sandbox
属性に allow-scripts
と allow-same-origin
の両方を追加しないことです。この場合、埋め込みコンテンツは、サイトのスクリプトの実行を停止する同一オリジン・セキュリティポリシーをバイパスし、JavaScript を使用してサンドボックスを完全に無効にします。
メモ: 攻撃者が欺いて悪意のあるコンテンツ(iframe 外にある)を直接訪問させることができれば、サンドボックスは保護を提供しません。特定のコンテンツが悪意のあるコンテンツ(ユーザ生成コンテンツなど)である可能性がある場合は、別の{{glossary("domain","ドメイン")}}からメインサイトへ配信してください。
{{Glossary("CSP")}} はコンテンツセキュリティポリシーの略で、HTML 文書のセキュリティを強化するために設計された一連の HTTP ヘッダー(ウェブサーバーから配信されたときにウェブページとともに送信されるメタデータ)を提供します。<iframe>
を保護する場合、適切な X-Frame-Options ヘッダーを送信するようにサーバーを構成できます。これにより、他のウェブサイトがそのウェブページにあなたのコンテンツを埋め込むのを防ぐことができます({{interwiki('wikipedia','クリックジャッキング')}}や他の攻撃のホストを可能にする)。以前に見たように、これはまさに MDN 開発者が行ったことです。
メモ: Frederik Braun 氏の投稿 X-Frame-Options セキュリティヘッダーについて(英語)で、このトピックの背景情報を読むことができます。明らかに、これは、この記事の詳述の範囲外です。
{{htmlelement("embed")}} 要素と {{htmlelement("object")}} 要素は、{{htmlelement("iframe")}} とは異なる機能を果たします。これらの要素は、Java アプレットや Flash などのプラグイン技術、PDF(ブラウザーで PDF プラグインを使用して表示できる)、動画、SVG、画像などのコンテンツを含む、複数のタイプの外部コンテンツを埋め込む汎用埋め込みツールです!
メモ: プラグインは、ブラウザーがネイティブに読むことができないコンテンツへのアクセスを提供するソフトウェアです。
しかし、あなたはこれらの要素を大いに利用することはまずありません。アプレットは何年も使われておらず、Flash は多くの理由から人気がなくなりました (下記の{{anch("The case against plugins","プラグインに対するケース")}}を参照)。PDF は埋め込まれたものよりもリンクされている傾向があり、画像や動画などの他のコンテンツには、それらを扱うためのずっと優れた、より簡単な要素があります。プラグインとこれらの埋め込み方法は、従来の技術ですが、イントラネットやエンタープライズプロジェクトのような特定の状況でそれらを見かけた場合に備えて言及しています。
プラグインのコンテンツを埋め込む必要がある場合の最低限必要な情報です。
{{htmlelement("embed")}} | {{htmlelement("object")}} | |
---|---|---|
埋め込みコンテンツの {{glossary("URL")}} | {{htmlattrxref('src','embed')}} | {{htmlattrxref('data','object')}} |
埋め込みコンテンツの正確な{{glossary("MIME type", 'メディアタイプ')}} | {{htmlattrxref('type','embed')}} | {{htmlattrxref('type','object')}} |
プラグインによって制御されるボックスの高さと幅 (CSS ピクセル単位) | {{htmlattrxref('height','embed')}} {{htmlattrxref('width','embed')}} |
{{htmlattrxref('height','object')}} {{htmlattrxref('width','object')}} |
プラグインにパラメータとして供給するための名前と値 | それらの名前と値を持つ特別な属性 | <object> 内に含まれる単一タグの {{htmlelement("param")}} 要素 |
利用不可能なリソースに対する代替として独立した HTML コンテンツ | サポートされていません(<noembed> は廃止されました) |
<object> 内の、<param> 要素の後に含まれる |
メモ: <object>
には、data
属性、type
属性、またはその両方が必要です。両方を使用する場合は、{{htmlattrxref('typemustmatch','object')}} 属性を使用することもできます(この記事の執筆時点では、Firefox でのみ実装されています)。typemustmatch
は、type
属性が正しいメディアタイプを提供していない限り、埋め込みファイルが実行されないようにします。typemustmatch
は、異なる{{glossary("origin","オリジン")}}のコンテンツを埋め込んでいる場合に、大きなセキュリティ上の利点をもたらすことができます(攻撃者がプラグインを介して任意のスクリプトを実行することを防ぐことができます)。
次に、{{htmlelement("embed")}} 要素を使用して Flash ムービーを埋め込む例を示します(Github でライブを見て、ソースコードも確認してください)。
<embed src="whoosh.swf" quality="medium" bgcolor="#ffffff" width="550" height="400" name="whoosh" align="middle" allowScriptAccess="sameDomain" allowFullScreen="false" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer">
かなり恐ろしいですね。Adobe Flash ツールで生成された HTML は、<embed>
要素が埋め込まれた <object>
要素を使用して、すべてのベースをカバーするために悪化する傾向がありました(例を参照してください)。Flash は、HTML5 動画の代替コンテンツとしても使用されていましたが、これは必要ではないと見られています。
次に、PDF をページに埋め込む <object>
の例を見てみましょう(ライブのサンプルとソースコードを参照)。
<object data="mypdf.pdf" type="application/pdf" width="800" height="1200" typemustmatch> <p>PDF プラグインはありませんが、 <a href="mypdf.pdf">PDF ファイルをダウンロードできます。 </a> </p> </object>
PDF は紙とデジタルの間の必要な足がかりでしたが、多くのアクセシビリティ上の課題(英語)があり、小さな画面では読みにくい場合があります。それらはまだいくつかのサークルで人気がある傾向がありますが、ウェブページに埋め込むのではなく、ダウンロードしたり、別のページで読むことができるように、リンクする方がはるかに優れています。
かつて、プラグインはウェブ上で不可欠でした。映画をオンラインで見るために Adobe Flash Player をインストールしなければならない時代を覚えていますか? そして、常に Flash Player と Java Runtime Environment のアップデートに関する迷惑な警告を受けていました。ウェブ技術はこれまでより堅牢に成長し、その時代は終わりを告げています。ほとんどのアプリケーションでは、プラグインに依存するコンテンツの配信をやめ、代わりにウェブテクノロジを活用し始めてください。
Note: その固有の問題点と Flash のサポート不足により、 Adobe は2020年末に Flash のサポートを終了すると発表しました。 2020年1月の時点で、ほとんどのブラウザーは既定で Flash コンテンツをブロックしており、2020年12月31日までにはすべてのブラウザーで Flash 機能が完全に削除されます。それ以降は、既存の Flash コンテンツにアクセスできなくなります。
だから何をすべきか? 双方向性が必要な場合、HTML と {{glossary("JavaScript")}} は、Java アプレットや旧式の ActiveX/BHO 技術を必要とせずに、簡単に仕事を完了させることができます。Adobe Flash に頼る代わりに、メディアの要求に合わせて HTML5 動画、ベクターグラフィックスに SVG、複雑な画像やアニメーションに Canvas を使用することができます。Peter Elst は、数年前にすでに、Adobe Flash が特殊なゲームやビジネスアプリケーションを除いて、仕事のための適切なツールではないことを書いていました(英語)。ActiveX に関しては、Microsoft の {{glossary("Microsoft Edge","Edge")}} ブラウザーでさえサポートされなくなりました。
この記事はここまでですが、最も重要な情報を覚えていますか?先に進む前に、この情報を保持しているかどうかを確認するためのテストをいくつか見つけることができます — マルチメディアと埋め込みのスキルのテストを参照してください。
ウェブ文書に他のコンテンツを埋め込むという話題は、すぐに非常に複雑になる可能性があるので、関連する技術のより高度な機能のいくつかを示唆しながらも、すぐに関連すると思われる単純で使い慣れた方法で紹介しようとしました。まず、あなたのページに地図や動画などの第三者のコンテンツを含めること以外に埋め込みを使用する可能性は低いです。しかし、経験が増すにつれて、より多くの用途を見つけることになるでしょう。
ここで説明したもの以外にも、外部コンテンツの埋め込みを含む他の多くの技術があります。以前の記事では {{htmlelement("video")}}、{{htmlelement("audio")}}、{{htmlelement("img")}} などいくつかを見ましたが、JavaScript で生成された 2D および 3D グラフィックスの場合は {{htmlelement("canvas")}}、ベクターグラフィックスを埋め込む場合は {{SVGElement("svg")}} など、他にも見い出されるものがあります。モジュールの次の記事では SVG を見ていきます。
{{PreviousMenuNext("Learn/HTML/Multimedia_and_embedding/Video_and_audio_content", "Learn/HTML/Multimedia_and_embedding/Adding_vector_graphics_to_the_Web", "Learn/HTML/Multimedia_and_embedding")}}