Ich schreibe eine iframe-basierte Facebook-App. Nun möchte ich dieselbe HTML-Seite verwenden, um die normale Website sowie die Canvas-Seite innerhalb von Facebook darzustellen. Ich möchte wissen, ob ich feststellen kann, ob die Seite innerhalb des iframe oder direkt im Browser geladen wurde?
Antworten
Zu viele Anzeigen?Die akzeptierte Antwort hat bei mir innerhalb des Inhaltsskripts einer Firefox 6.0 Erweiterung (Addon-SDK 1.0) nicht funktioniert: Firefox führt das Inhaltsskript in jedem: dem Top-Level-Fenster und in allen Iframes aus.
Innerhalb des Inhaltsskripts erhalte ich die folgenden Ergebnisse:
(window !== window.top) : false
(window.self !== window.top) : true
Das Seltsame an dieser Ausgabe ist, dass sie immer gleich ist, unabhängig davon, ob der Code in einem Iframe oder im Top-Level-Fenster ausgeführt wird.
Andererseits scheint Google Chrome mein Inhaltsskript nur einmal innerhalb des Fensters der obersten Ebene auszuführen, so dass die obige Vorgehensweise überhaupt nicht funktionieren würde.
Was bei mir schließlich in einem Inhaltsskript in beiden Browsern funktioniert hat, ist Folgendes:
console.log(window.frames.length + ':' + parent.frames.length);
Ohne iframes wird dies gedruckt 0:0
in einem Fenster der obersten Ebene, das einen Rahmen enthält, wird Folgendes gedruckt 1:1
und in dem einzigen Iframe eines Dokuments wird Folgendes gedruckt 0:1
.
Dadurch kann meine Erweiterung in beiden Browsern feststellen, ob iframes vorhanden sind, und zusätzlich in Firefox, ob sie innerhalb eines iframes ausgeführt wird.
Best-for-now Legacy Browser Frame Breaking Script
Die anderen Lösungen haben bei mir nicht funktioniert. Diese Lösung funktioniert bei allen Browsern:
Eine Möglichkeit, sich gegen Clickjacking zu schützen, besteht darin, ein "Frame-Breaker"-Skript in jede Seite einzubauen, die nicht gerahmt werden soll. Die folgende Methode verhindert, dass eine Webseite auch in älteren Browsern, die den X-Frame-Options-Header nicht unterstützen, eingerahmt wird.
Fügen Sie im HEAD-Element des Dokuments Folgendes hinzu:
<style id="antiClickjack">body{display:none !important;}</style>
Wenden Sie zunächst eine ID auf das Stilelement selbst an:
<script type="text/javascript">
if (self === top) {
var antiClickjack = document.getElementById("antiClickjack");
antiClickjack.parentNode.removeChild(antiClickjack);
} else {
top.location = self.location;
}
</script>
Auf diese Weise kann alles im HEAD des Dokuments stehen und Sie benötigen nur eine Methode/Taglib in Ihrer API.
Referenz: https://www.codemagi.com/blog/post/194
Da Sie diese Frage im Zusammenhang mit einer Facebook-App stellen, sollten Sie in Erwägung ziehen, dies auf dem Server zu erkennen, wenn die erste Anfrage gestellt wird. Facebook gibt eine Reihe von Querystring-Daten weiter, einschließlich des fb_sig_user-Schlüssels, wenn er von einem iframe aufgerufen wird.
Da Sie diese Daten wahrscheinlich ohnehin in Ihrer Anwendung überprüfen und verwenden müssen, verwenden Sie sie, um den entsprechenden Kontext für die Darstellung zu bestimmen.
Verwenden Sie diese Javascript-Funktion als Beispiel dafür, wie Sie dies erreichen können.
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;
}
4 Stimmen
Ein paar schöne Möglichkeiten (einschließlich Kommentare): tommcfarlin.com/check-ob-eine-seite-ist-in-einem-iframe
3 Stimmen
Externe Links sind kein gutes Mittel, um Fragen zu beantworten. Vor allem, wenn sich der Inhalt dieser externen Links reduzieren lässt auf
return window.location !== window.parent.location
.