web-dev-qa-db-ja.com

X-Frame-Optionsを検出するクライアント側の方法はありますか?

X-Frame-Optionsヘッダーが原因でページがフレームに表示されないことを検出する良い方法はありますか?サーバーサイドでページをリクエストしてヘッダーを探すことができることはわかっていますが、このエラーをキャッチするためのメカニズムがブラウザーにあるかどうか知りたいと思っていました。

41
Newtang

わかりました、これは古いですがまだ関連しています。

Fact: iframeがX-Frame-OptionsによってブロックされたURLをロードするとき、ロード時間は非常に短いです。

Hack:なので、オンロードがすぐに発生した場合、それはおそらく Xフレームオプションです。問題。

免責事項:これはおそらく私が書いた「最もハッキリした」コードの1つなので、あまり期待しないでください。

var timepast=false; 
var iframe = document.createElement("iframe");

iframe.style.cssText = "position:fixed; top:0px; left:0px; bottom:0px; right:0px; width:100%; height:100%; border:none; margin:0; padding:0; overflow:hidden; z-index:999999;";
iframe.src = "http://pix.do"; // This will work
//iframe.src = "http://google.com"; // This won't work
iframe.id = "theFrame";

// If more then 500ms past that means a page is loading inside the iFrame
setTimeout(function() {
    timepast = true;
},500);

if (iframe.attachEvent){
    iframe.attachEvent("onload", function(){
    if(timepast) {
            console.log("It's PROBABLY OK");
        }
        else {
            console.log("It's PROBABLY NOT OK");
        }
    });
} 
else {
    iframe.onload = function(){
        if(timepast) {
            console.log("It's PROBABLY OK");
        }
        else {
            console.log("It's PROBABLY NOT OK");
        }
    };
}
document.body.appendChild(iframe);
12
Iftach

免責事項:2012年に私が書いたこの回答(当時のChromeのバージョンは〜20)は古くなっているので、ここでは履歴目的でのみ使用します。自分の責任で読んで使用してください。


OK、これは少し古い質問ですが、Chrome/Chromiumについて私が見つけたもの(完全な答えではありません)です。

外部アドレスを指すフレームがロードされたかどうかを検出する方法は、単にcontentWindowまたはドキュメントにアクセスしようとすることです。

これが私が使ったコードです:

element.innerHTML = '<iframe class="innerPopupIframe" width="100%" height="100%" src="'+href+'"></iframe>';
myframe = $(element).find('iframe');

それじゃあ、後でね:

try {
    var letstrythis = myframe.contentWindow;
} catch(ex) {
    alert('the frame has surely started loading');
}

事実は、X-Frame-Optionsがアクセスを禁止している場合、myFrame.contentWindowがアクセス可能になります。

ここでの問題は、私が「その後」と呼んだものです。何に頼るかはまだわかりません。どのイベントをサブスクライブして、いつテストを実行するのがよいかを見つけます。

7
BiAiB

これは @ Iftach の回答に基づいていますが、少しハックが少ないです。

iframe.contentWindow.length > 0これは、iframeが正常に読み込まれたことを示しています。

さらに、iframe onloadイベントが5秒以内に発生したかどうかを確認し、それも警告します。これは、混合されたコンテンツの読み込みの失敗をキャッチします(ハックな方法ですが)。

var iframeLoaded = false;
var iframe = document.createElement('iframe');

// ***** SWAP THE `iframe.src` VALUE BELOW FOR DIFFERENT RESULTS ***** //
// iframe.src = "https://davidsimpson.me"; // This will work
iframe.src = "https://google.com"; // This won't work

iframe.id = 'theFrame';
iframe.style.cssText = 'position:fixed; top:40px; left:10px; bottom:10px;'
 + 'right:10px; width:100%; height:100%; border:none; margin:0; padding:0; overflow:hidden; z-index:999999;';

var iframeOnloadEvent = function () {
    iframeLoaded = true;
  var consoleDiv = document.getElementById('console');
    if (iframe.contentWindow.length > 0) {
    consoleDiv.innerHTML = '✔ Content window loaded: ' + iframe.src;
    consoleDiv.style.cssText = 'color: green;'
    } else {
    consoleDiv.innerHTML = '✘ Content window failed to load: ' + iframe.src;
    consoleDiv.style.cssText = 'color: red;'
    }
} 

if (iframe.attachEvent){
    iframe.attachEvent('onload', iframeOnloadEvent);
} else {
    iframe.onload = iframeOnloadEvent;
}
document.body.appendChild(iframe);

// iframe.onload event doesn't trigger in firefox if loading mixed content (http iframe in https parent) and it is blocked.
setTimeout(function () {
    if (iframeLoaded === false) {
        console.error('%c✘ iframe failed to load within 5s', 'font-size: 2em;');
    consoleDiv.innerHTML = '✘ iframe failed to load within 5s: ' + iframe.src;
    consoleDiv.style.cssText = 'color: red;'    
  }
}, 5000);

こちらのライブデモ- https://jsfiddle.net/dvdsmpsn/7qusz4q3/ -関連するブラウザでテストできます。

執筆時点では、Chrome、Safari、Opera、Firefox、Vivaldi、およびInternet Explorer 11の現在のバージョンで動作します。他のブラウザーではテストしていません。

2
dvdsmpsn

少なくともChromeでは、iframe.onloadイベントがトリガーされないため、ロードの失敗に気付くでしょう。これは、ページがiframingを許可しない可能性があることを示すインジケーターとして使用できます。

0
apenwarr

オンラインテストツールが役立つ場合があります。私は https://www.hurl.it/ を使用しました。応答ヘッダーをはっきりと見ることができます。 X-frame-optionを探します。値が拒否の場合-iframeに表示されません。同じオリジン-同じドメインからのみ、許可-特定のWebサイトから許可します。

別のツールを試したい場合は、単に「httpリクエストテストオンライン」でグーグルできます。

0
OlgaY

私が考えることができる唯一のことは、URLのAJAX要求をプロキシし、ヘッダーを確認し、X-Frame-Optionsがない場合は、それをiframe。理想からはほど遠いが、何もないよりはましだ。

0
Newtang