はじめに
iframeを使ってあるサイトのhtmlページを表示したいと思って、実行すると同じオリジンではないと、エラーになることがあります。
また、自サイトのページを表示させるとうまく表示できたりもします。この差は何なんだろうといろいろ調べてみると、やはりオリジンチェックが原因でした。今回、テスト用のプラグインを作成しました。
テストサンプル
今回、2,3の外部ページでテストしてみました。テストするためには、以下のプラグインをダウンロードしてからフォルダーへ解凍し、そのフォルダーを拡張機能のインストール時に指定します。そうすることで、chromeブラウザーへプラグインをインストールできます。
TinyYoutubePlayerPlusOriginCheckプラグイン(ダウンロード)
テスト起動方法
このテストはオリジンのページでctrlKey+click(マウスの左ボタン)すると、オリジンテストの選択ポップ画面(プラグインで表示)が表示されます。そこで、iframeで表示するページをチェックして選択します。すると、指定のページをiframeに表示しようとします。オリジンエラーの場合はエラーが出ます。その他の場合は指定のページが表示されます。
favoriteページを選択するとyoutubeプレーヤーページを表示し、再生ができます。
失敗する例(アマゾンのページでオリジンエラーを返却)
(1) yahooページでアマゾンページを表示するテスト
この場合、オリジンは一致しません。yahooページとアマゾンページなので同じオリジンではありません。
(2) yahooページでyahooページを表示するテスト
この場合は同じオリジンのため、iframeで表示されています。
(3)オリジンは異なりますが表示されるテスト
この場合、オリジンは異なりますが表示されています。それは、このfavoriteページではphpファイルで
header("Access-Control-Allow-Origin: *");を指定しているためです。
プラグインを使ってyahooページのbodyにiframe要素をアペンドをしてみます。
この時、iframeにはアマゾンのページを指定しておきます。
let html ="<!-- youtubeラジオ -->\n\
<div id='youtube_radio' style='background-color:lightyellow;z-index:999999;border: 10px solid lawngreen; width: 170px;height: 265px; position: fixed;zoom: 1.5;top:42px;right:0px;zoom:1.5;'>\n\
<img style='zoom:0.5;' src='https://favorite.tecoyan.net/slim/images/radio_small.png'><span style='zoom:0.9;position:absolute;top:0px;right:10px;font-size:10px;'>TinyYoutubePlayerPlusプラグインv1.0</span>\n\
<iframe class='iframe_radio' style='position:relative;top:0px;border:solid 2px orange; width:150px;height:220px;' src='https://favorite.tecoyan.net/slim/index_radio_simple.php?vid=YNQT68uHpyg&title=%E4%BB%8A%E6%97%A5%E3%81%AE%E6%97%A5%E3%81%AF%E3%81%95%E3%82%88%E3%81%86%E3%81%AA%E3%82%89%E3%80%80%E6%A3%AE%E5%B1%B1%E8%89%AF%E5%AD%90%E3%80%801967&url=&db_id=3120'></iframe>\n\
</div>";
$("body").append(html);
失敗した時のデバッガーのコンソールには、以下のメッセージが表示されます。
Refused to display 'https://qiita.com/' in a frame because it set 'X-Frame-Options' to 'sameorigin'.
これは、このページが出力したメッセージで、「sameorigin」のみ許可されますということです。
成功した例(すべてのサイトでオリジンを許可した例)
当然ですが、この場合は、エラーは出ません。
favoriteページでは、すべてのphpファイルでオリジンチェックはしていません。
それは、
header("Access-Control-Allow-Origin: *");
を指定したいるため、すべてのオリジンを許可しています。
外部ページでは、'X-Frame-Options'に'sameorigin'を指定しているため、同じオリジンでのみ許可しています。
テスト結果
以下のような結果が得られました。
例えば、yahoo!Japanページに以下のiframeページを表示させるとすると、
(1)yahoo!Japanページは表示されます。同じオリジンのためです。
(2)Qiitaページは、オリジンが異なるため、エラー表示されます。
(3)アマゾンページは、オリジンが異なるため、エラー表示されます。
(4)徳洲会ページは、オリジンが異なるため、エラー表示されます。
(5)favoriteページは表示されます。これは、オリジンは異なりますが、phpファイルですべてのオリジンを許可しているためです。(前掲)
当たり前のことですが
yahooページやアマゾンなどのページでは、利用者からサーバーへhttpリクエストを出すときにheaderで"same origin"指定しています。そのため、iframeでそれらのページを表示させようとしても、サーバーでその指定を確認してオリジンが異なれば(例えばアマゾンページでyahooページをiframeで表示させようとした場合)、利用者側へオリジンエラーのメッセージを返却します。
あとがき
ここでは、テスト用のプラグインを使用してオリジンチェックを目で確かめられるようにしました。このテスト用のプラグインをChromeブラウザーにインストールすれば、あらゆるページでiframeのテストを行うことができます。ただし、このプラグインで選択できる特定のページ(5項目)に限ってですが。