JavaScriptでiframeの内容を取得する方法
スポンサーリンク
このドキュメントの内容は、以下の通りです。
- はじめに
- 同一オリジンポリシーとは
- ページがロードされるまで待つ
- iframe内のコンテンツの取得方法
- iframe内にコンテンツを追加する方法
- jQueryを利用して、iframe内のコンテンツを取得する方法
- クロスドメインで試した場合
- まとめ
はじめに
ウェブサイトでは、 HTML や CSS 、 JavaScript などの技術がふんだんに活用されています。ウェブページのコンテンツは、テキスト以外に画像やビデオなどのコンテンツが利用されます。コンテンツは、フレーム(frame)によってページ内を分割したり、 iframe を利用して、ページ内にページのコンテンツを表示できます。iframe を利用することで、外部サイトのコンテンツをページ内に表示できるなどのメリットがあります。
JavaScriptでiframe内のコンテンツを取り出したり、操作する方法を紹介します。 単純な JavaScript での例や JavaScriptのライブラリである jQuery を利用した例も併せて紹介します。
また、同一オリジンポリシーについても簡単に紹介します。
同一オリジンポリシーとは
ここでは、前提知識として、同一オリジンポリシーを紹介します。同一オリジンポリシーをご存知の方は、読み飛ばして頂いて構いません。ウェブの世界には、同一オリジンポリシー(同一生成元ポリシー)と呼ばれるものがあります。
同一オリジンポリシーは、あるオリジンから読み込まれたテキストやスクリプトは、そのリソースから他のオリジンにアクセスできないように制限します。
あるオリジンが、自身のオリジンにアクセスする場合は、制限されません。自分のウェブサイトのリソースは、自分で自由に利用できます。
例えば、グーグルのウェブページ (www.google.com) からfacebook (facebook.com) のリソースにアクセスできない、ということです。このポリシーは、セキュリティやプライバシーを守るためのものです。
なぜ、セキュリティやプライバシーが守られるのか?ということですが、あるサイトから自由に google や facebook のリソースにアクセスができるとしたら、なにが起きるでしょうか?本来、本人しか閲覧できないはずの、Gmail のメールを第三者のスクリプトがアクセスできたり、 facebook のメッセンジャーの内容を第三者のスクリプトでのぞき見したり、メールやメッセージを送信できる可能性が出てきます。
あるサイトにアクセスしたら、自分のウェブメールの内容を第三者に見られた、といったことがないように、同一オリジンポリシーによって守られているのです。
つまり、あなたのサイトで、他のサイトを iframe で呼び出しても、中身にはアクセスができません。
ページがロードされるまで待つ
この例では、すぐにロードされるようなページのため、問題にはならないかもしれませんが、一般的には、 iframe のページがロードされるまで待つ必要があります。
この記事では、 window.onload を利用して、ページがロードされるのを待ちます。iframe でほかのページを呼び出しているページの JavaScript は、 iframe 内のコンテンツが配信されるまで、待ちます。
window.onload を使わずに、ロードされるのを待たない場合、 iframe 内のコンテンツが取得できない可能性があります。
実際に iframe のコンテンツの配信を10秒遅らせて試してみたところ、JavaScript はデータを取得できませんでした。
iframe内のコンテンツの取得方法
JavaScriptで ifrmae内のコンテンツを取得するには、iframeのcontentWindowのdocumentにアクセスします。
var doc = document.getElementsByTagName("iframe")[0].contentWindow.document; alert(doc.body.innerHTML);
iframe.html
iframeのサンプルコード。doc は変数名ですので、適当に読み替えてください。
この例では、 doc.body.innerHTMLや doc.body.innerTextで取得できます。
body としているので、 body タグに囲まれている内容になります。
iframe <iframe src="abc.html"> </iframe> <script type="text/javascript"> window.onload = function() { try { var doc = document.getElementsByTagName("iframe")[0].contentWindow.document; } catch(e) { alert(e); } alert(doc.body.innerHTML); } </script>
abc.html
iframeで表示するhtmlページは以下の通りです。
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title>ABC</title> </head> <body> <h1>This is ABC</h1> <div>Hoge hoge.</div> </body> </html>
innerHTML では、以下が取得できます。
<h1>This is ABC</h1> <div>Hoge hoge.</div>
innerText では、以下が取得できます。
This is ABC Hoge hoge.
ローカルで実行する場合の注意点
ローカルのファイルを直接 Google Chrome で開いた場合、下記のエラーが出ました。
SecurityError: Blocked a frame with origin "null" from accessing a cross-origin frame.
ローカルのウェブサーバ経由でアクセスした場合は、問題なく、iframe 内のコンテンツが取得できました。
ウェブサーバは何を利用しても構いません。 Apache HTTPD, Nginx など、お好きなものをご利用ください。
PHP のビルドインサーバなどを利用すると簡単です。サンプルのプログラムの動作確認でよく利用しています。 PHP を使うメリットはありませんが、ただの HTML のページの配信であっても、利用できます。
以下のコマンドでPHPのビルドインサーバを起動します。
php -S 0.0.0.0:8080
php を起動したときのカレントのディレクトリのコンテンツが配信できます。
ビルドインサーバを起動したあとに、ブラウザで、以下のURLにアクセスすることで動作の確認ができます。
http://127.0.0.1:8080/iframe.html
Winodwsの場合は、WSL (Windows Subsystem for Linux) で Ubuntu などの Linux 環境を作って、そこに PHP をインストールすると簡単にPHPの環境が作れます。
iframe内にコンテンツを追加する方法
iframe内にdivを追加するには、createElement でdivを作成し、iframe内のbodyにappendChildでそれを追加します。
try { var doc = document.getElementsByTagName("iframe")[0].contentWindow.document; var d = doc.createElement("div"); doc.body.appendChild(d); } catch(e) { alert(e); }
jQueryを利用して、iframe内のコンテンツを取得する方法
JavaScript のライブラリの1つである jQueryで iframe 内のコンテンツを取得する方法を紹介します。
たとえば、このような iframe があったとします。
<iframe id="iframe-id" src="iframe3-jquery-page.php"></iframe>
jquery は、適当なものを利用してください。jQuery のライブラリは、 https://jquery.com/download/ からダウンロードできます。
yarn や npm を利用することもできます。
npm install jquery yarn add jquery
on でロードを待ちます。ページのダウンロードに時間が掛かっても、待ってくれます。
下記の例では、findでページ内のタグを検索して、その中の html を取得します。
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script> <script langunage="text/javascript"> $('#iframe-id').on('load', function() { console.log("loaded"); var iframe = $("#iframe-id"); console.log(iframe.contents().find('body').html() ); }); </scriot>
クロスドメインで試した場合
クロスドメイン(CrossDomain)とは、異なるドメインにアクセスする、という意味です。
hoge.com から google.com へアクセスする、といったことをクロスドメインアクセスという風に呼ばれます。
iframe で読み込むページを別のドメインのページ(なんでも構いませんが、ここでは、http://www.google.co.jp/ にしました)にしてみました。
その結果、マイクロソフトのIE(Internet Explorer, 2020年代にはマイクロソフトのブラウザはEDGEへ)だと、以下のエラーになりました。
[object Error]
OSS業界の雄である Mozilla(モジラ)のfirefox(ファイアーフォックス)では、以下のエラーになりました。
uncaught exception: Permission denied to get property HTMLDocument.body
セキュリティ的に当然のことではあります。
まとめ
- 同じ FQDN のページのコンテンツは、 JavaScript で取得できます。
- 同一オリジンポリシーがあり、クロスドメインのページのコンテンツは JavaScript で取得できません
スポンサーリンク
スポンサーリンク
いつもシェア、ありがとうございます!
もっと情報を探しませんか?
関連記事
最近の記事
- パナソニック ジェットウォッシャードルツ EW-DJ61-Wのホースの修理
- LinuxセキュリティモジュールIntegrity Policy Enforcement
- アマゾンのEcho Show 5を買ったのでレビューします
- アマゾンのサイバーマンデーはAlexa Echo Show 5が安い
- Android スマートフォン OnePlus 7T と OnePlus 7の違い
- Android スマートフォン OnePlus 7 をAndroid10にアップデートしてみた
- クレジットカードのバーチャルカードの比較のまとめ
- 活動量計 Xiaomi Mi Band 4を買ってみたのでレビュー
- Android スマートフォン OnePlus 7 のレビュー
- AliExpressでスマートフォンを買い物してみた
- パソコンのホコリ対策 レンジフードフィルターと養生テープ
- 80PLUS GOLDのPC電源ユニットAntec NeoEco 750 Goldのレビュー
- イギリスの付加価値税 VAT は払い戻しを受けられる
- イギリスのロンドンでスーツケースなど荷物を預けられる場所は
- イギリスのロンドンで地下鉄やバスに乗るならオイスターカードを使おう
- イギリスのヒースロー空港からロンドン市内への行き方
- 航空便でほかの航空会社に乗り継ぎがある場合のオンラインチェックイン
- SFC会員がANA便ではなくベトナム航空のコードシェアを試して解ったこと
- ベトナムの入国審査でeチケットの掲示が必要だった話
- シアトルの交通ICカードはオルカカード(Orca)です
人気のページ
- Windows7 IME 辞書ツールで単語の登録に失敗しました
- C言語 popen()でコマンドを実行して出力を読み込む
- Windows7で休止状態にする方法
- CentOS MySQLの起動、停止、再起動
- loggerコマンドでsyslogにエラーを出力する方法
- パソコンパーツの買取をしてくれる店のまとめ
- Java Mapの使い方 get(),put(),remove(),size(),clear()
- 楽天のRポイントカードを作ってみた
- iPhone 5 から iPhone 6 に乗り換えたのでレビュー
- netstatコマンドのステータスの意味
スポンサーリンク
過去ログ
2020 : 01 02 03 04 05 06 07 08 09 10 11 122019 : 01 02 03 04 05 06 07 08 09 10 11 12
2018 : 01 02 03 04 05 06 07 08 09 10 11 12
2017 : 01 02 03 04 05 06 07 08 09 10 11 12
2016 : 01 02 03 04 05 06 07 08 09 10 11 12
2015 : 01 02 03 04 05 06 07 08 09 10 11 12
2014 : 01 02 03 04 05 06 07 08 09 10 11 12
2013 : 01 02 03 04 05 06 07 08 09 10 11 12
2012 : 01 02 03 04 05 06 07 08 09 10 11 12
2011 : 01 02 03 04 05 06 07 08 09 10 11 12
2010 : 01 02 03 04 05 06 07 08 09 10 11 12
2009 : 01 02 03 04 05 06 07 08 09 10 11 12
2008 : 01 02 03 04 05 06 07 08 09 10 11 12
2007 : 01 02 03 04 05 06 07 08 09 10 11 12
2006 : 01 02 03 04 05 06 07 08 09 10 11 12
2005 : 01 02 03 04 05 06 07 08 09 10 11 12
2004 : 01 02 03 04 05 06 07 08 09 10 11 12
2003 : 01 02 03 04 05 06 07 08 09 10 11 12