回答:
同じ発信元ポリシーwindow.top
により、ブラウザはへのアクセスをブロックできます。IEのバグも発生します。ここに作業コードがあります:
function inIframe () {
try {
return window.self !== window.top;
} catch (e) {
return true;
}
}
top
とself
は両方ともwindow
(と共にparent
)オブジェクトなので、ウィンドウがトップウィンドウかどうかがわかります。
window.self !== window.top
戻ります。true
frame
iframe
親と同じ原点にあるiframe内にある場合、window.frameElement
メソッドはウィンドウが埋め込まれている要素(iframe
またはなどobject
)を返します。それ以外の場合、トップレベルのコンテキストでブラウジングする場合、または親フレームと子フレームの生成元が異なる場合は、と評価されnull
ます。
window.frameElement
? 'embedded in iframe or object'
: 'not embedded or cross-origin'
これは、すべての最新ブラウザで基本的にサポートされているHTML標準です。
null
の内側と外側iframe
Returns the element (such as <iframe> or <object>) in which the window is embedded, or null if the element is either top-level or is embedded into a document with a different script origin; that is, in cross-origin situations.
RoBorgは正しいですが、私は付記を付けたかったです。
IE7 / IE8では、Microsoftがブラウザにタブを追加したときに、注意を怠るとJSに大混乱を引き起こす1つの問題が発生しました。
このページレイアウトを想像してください。
MainPage.html
IframedPage1.html (named "foo")
IframedPage2.html (named "bar")
IframedPage3.html (named "baz")
フレーム "baz"でリンクをクリックします(ターゲットがなく、 "baz"フレームに読み込まれます)。
ロードされたページがspecial.htmlと呼ばれる場合、JSを使用して、「it」に「bar」という名前の親フレームがあるかどうかを確認します。この場合、trueが返されます(予期されています)。
次に、special.htmlページが読み込まれたときに、親フレームをチェックし(存在とその名前を確認し、 "bar"の場合はそれ自体をバーフレームに再読み込みします)。
if(window.parent && window.parent.name == 'bar'){
window.parent.location = self.location;
}
ここまでは順調ですね。今バグが来る。
通常のように元のリンクをクリックして「baz」フレームにspecial.htmlページをロードする代わりに、中クリックするか、新しいタブで開くことを選択したとします。
その新しいタブが読み込まれると(親フレームはまったくありません!)IEはページ読み込みの無限ループに入ります!IEはJavaScriptのフレーム構造を「コピー」して、新しいタブには親があり、その親には「バー」という名前があるためです。
良いニュースは、そのチェックです:
if(self == top){
//this returns true!
}
その新しいタブではtrueが返されるため、この奇妙な条件をテストできます。
window.parent
です。
受け入れられた回答が、Firefox 6.0 Extension(Addon-SDK 1.0)のコンテンツスクリプト内で機能しませんでした。Firefoxは、トップレベルウィンドウとすべてのiframeのそれぞれでコンテンツスクリプトを実行します。
コンテンツスクリプト内では、次の結果が得られます。
(window !== window.top) : false
(window.self !== window.top) : true
この出力の奇妙な点は、コードがiframe内で実行されているか、最上位ウィンドウ内で実行されているかに関係なく、常に同じであることです。
一方、Google Chromeはコンテンツスクリプトをトップレベルウィンドウ内で1回だけ実行するようなので、上記はまったく機能しません。
両方のブラウザーのコンテンツスクリプトで私にとって最終的に機能したのは次のとおりです。
console.log(window.frames.length + ':' + parent.frames.length);
iframeがなければ0:0
、これは印刷されます。1つのフレームを含むトップレベルウィンドウで印刷され1:1
、ドキュメントの唯一のiframeで印刷され0:1
ます。
これにより、拡張機能は、iframeが存在する場合は両方のブラウザーで、さらにiframeの1つ内で実行されている場合はFirefoxで判別できます。
document.defaultView.self === document.defaultView.top
またはを試してくださいwindow !== window.top
。FirefoxのアドオンSDKのコンテンツスクリプトでは、グローバルself
オブジェクトはメインスクリプトとの通信に使用されるオブジェクトです。
この例が古いWebブラウザーでどのように機能するかはわかりませんが、IE、Firefox、Chromeでこれを使用すると問題が発生しません。
var iFrameDetection = (window === window.parent) ? false : true;
!(window===window.parent)
私はこれを使っています:
var isIframe = (self.frameElement && (self.frameElement+"").indexOf("HTMLIFrameElement") > -1);
.indexOf("HTMLIFrameElement")
ですか?
これを実現する方法の例として、このJavaScript関数を使用してください。
function isNoIframeOrIframeInMyHost() {
// Validation: it must be loaded as the top page, or if it is loaded in an iframe
// then it must be embedded in my own domain.
// Info: IF top.location.href is not accessible THEN it is embedded in an iframe
// and the domains are different.
var myresult = true;
try {
var tophref = top.location.href;
var tophostname = top.location.hostname.toString();
var myhref = location.href;
if (tophref === myhref) {
myresult = true;
} else if (tophostname !== "www.yourdomain.com") {
myresult = false;
}
} catch (error) {
// error is a permission error that top.location.href is not accessible
// (which means parent domain <> iframe domain)!
myresult = false;
}
return myresult;
}
他の解決策は私にとってはうまくいきませんでした。これはすべてのブラウザで動作します:
クリックジャッキングを防ぐ1つの方法は、フレーム化すべきではない各ページに「フレームブレーカー」スクリプトを含めることです。次の方法では、X-Frame-Options-HeaderをサポートしないレガシーブラウザーでもWebページがフレーム化されるのを防ぎます。
ドキュメントのHEAD要素に、次を追加します。
<style id="antiClickjack">body{display:none !important;}</style>
まず、スタイル要素自体にIDを適用します。
<script type="text/javascript">
if (self === top) {
var antiClickjack = document.getElementById("antiClickjack");
antiClickjack.parentNode.removeChild(antiClickjack);
} else {
top.location = self.location;
}
</script>
このようにして、すべてがドキュメントHEADにあり、APIで必要なメソッド/ taglibは1つだけです。
リファレンス:https : //www.codemagi.com/blog/post/194
私は実際にwindow.parentをチェックして使用しましたが、最近はwindowが循環オブジェクトであり、常に親キー、iframeまたはiframeがありません。
コメントがwindow.parentと比較することは難しいことを示唆しています。iframeが親とまったく同じWebページである場合、これが機能するかどうかはわかりません。
window === window.parent;
window.parent === window
はtrueです。だからあなたの答えは間違っています。そして、この比較はチェックに使用できます(少なくともChromeでは、別のブラウザーでテストしていませんでした)。
それは私が数回使用した古代のコードです:
if (parent.location.href == self.location.href) {
window.location.href = 'https://www.facebook.com/pagename?v=app_1357902468';
}
(parent.location == self.location)
parent.location
ます。それ以外の場合は例外がスローされます
ユーザーがFacebookページのタブまたはキャンバスからアプリにアクセスしているかどうかを知りたい場合は、署名付きリクエストを確認してください。それを取得しない場合、おそらくユーザーはFacebookからアクセスしていません。signed_requestフィールドの構造とフィールドの内容を確認するため。
php-sdkを使用すると、次のような署名付きリクエストを取得できます。
$signed_request = $facebook->getSignedRequest();
署名付きリクエストの詳細については、こちらをご覧ください。
https://developers.facebook.com/docs/reference/php/facebook-getSignedRequest/
そしてここ:
https://developers.facebook.com/docs/reference/login/signed-request/
これは私にとって最も簡単な解決策でした。
<p id="demofsdfsdfs"></p>
<script>
if(window.self !== window.top) {
//run this code if in an iframe
document.getElementById("demofsdfsdfs").innerHTML = "in frame";
}else{
//run code if not in an iframe
document.getElementById("demofsdfsdfs").innerHTML = "no frame";
}
</script>
このJavaScriptを各ページに記述します
if (self == top)
{ window.location = "Home.aspx"; }
その後、自動的にホームページにリダイレクトされます。