Ich schreibe eine iframe-basierte Facebook-App. Jetzt möchte ich dieselbe HTML-Seite verwenden, um die normale Website sowie die Canvas-Seite in Facebook zu rendern. Ich möchte wissen, ob ich feststellen kann, ob die Seite im Iframe oder direkt im Browser geladen wurde.
javascript
facebook
iframe
Akshat
quelle
quelle
Antworten:
Browser können den Zugriff
window.top
aufgrund derselben Ursprungsrichtlinie blockieren . IE-Fehler treten ebenfalls auf. Hier ist der Arbeitscode:top
undself
sind beidewindow
Objekte (zusammen mitparent
), sodass Sie sehen, ob Ihr Fenster das oberste Fenster ist.quelle
window.self !== window.top
kehrttrue
bei der Ausführung aus Inhaltenframe
, oderiframe
.In einem Iframe mit demselben Ursprung wie das übergeordnete
window.frameElement
Element gibt die Methode das Element (z. B.iframe
oderobject
) zurück, in das das Fenster eingebettet ist. Andernfalls wird beim Surfen in einem Kontext der obersten Ebene oder wenn der übergeordnete und der untergeordnete Frame unterschiedliche Ursprünge haben, eine Auswertung durchgeführtnull
.Dies ist ein HTML-Standard mit grundlegender Unterstützung in allen modernen Browsern.
quelle
frameElement
laut W3C eine SecurityError-Ausnahme in Ursprungs-übergreifenden Iframes ausgelöst wird ( WHATWG sagt, dass stattdessen null zurückgegeben werden sollte). Vielleicht möchten Sie es in einetry...catch
Anweisung einschließen.null
innen und außeniframe
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 ist korrekt, aber ich wollte eine Randnotiz hinzufügen.
In IE7 / IE8 haben Microsoft beim Hinzufügen von Tabs zu ihrem Browser eine Sache kaputt gemacht, die Ihrem JS Schaden zufügt, wenn Sie nicht vorsichtig sind.
Stellen Sie sich dieses Seitenlayout vor:
Jetzt klicken Sie in Frame "baz" auf einen Link (kein Ziel, lädt in den "baz" Frame), es funktioniert einwandfrei.
Wenn die Seite, die geladen wird, als special.html bezeichnet wird, verwendet JS, um zu überprüfen, ob "es" einen übergeordneten Frame mit dem Namen "bar" hat, wird true (erwartet) zurückgegeben.
Nehmen wir nun an, dass die Seite special.html beim Laden den übergeordneten Frame überprüft (auf Existenz und Namen, und wenn es sich um "Balken" handelt, lädt sie sich selbst in den Balkenrahmen neu, z
So weit, ist es gut. Jetzt kommt der Fehler.
Nehmen wir an, Sie klicken nicht wie gewohnt auf den ursprünglichen Link und laden die Seite special.html in den Rahmen "baz", sondern haben mit der mittleren Maustaste darauf geklickt oder sie in einem neuen Tab geöffnet.
Wenn dieser neue Tab geladen wird ( ohne übergeordnete Frames! ), Tritt der IE in eine endlose Schleife des Seitenladens ein! weil IE die Rahmenstruktur in JavaScript "kopiert", so dass die neue Registerkarte ein übergeordnetes Element hat und dieses übergeordnete Element den Namen "bar" hat.
Die gute Nachricht ist, dass überprüft wird:
In dieser neuen Registerkarte wird true zurückgegeben, und Sie können diese ungerade Bedingung testen.
quelle
window.parent
.Die akzeptierte Antwort hat bei mir im Inhaltsskript einer Firefox 6.0-Erweiterung (Addon-SDK 1.0) nicht funktioniert: Firefox führt das Inhaltsskript in jedem Fenster der obersten Ebene und in allen Iframes aus.
Im Inhaltsskript erhalte ich folgende Ergebnisse:
Das Seltsame an dieser Ausgabe ist, dass sie immer gleich ist, unabhängig davon, ob der Code in einem Iframe oder im Fenster der obersten Ebene ausgeführt wird.
Auf der anderen Seite scheint Google Chrome mein Inhaltsskript nur einmal im Fenster der obersten Ebene auszuführen, sodass das oben genannte überhaupt nicht funktioniert.
Was für mich in einem Inhaltsskript in beiden Browsern endlich funktioniert hat, ist Folgendes:
Ohne Iframes wird dies gedruckt
0:0
, in einem Fenster der obersten Ebene, das einen Frame enthält1:1
, und im einzigen Iframe eines Dokuments, das gedruckt wird0:1
.Dadurch kann meine Erweiterung in beiden Browsern feststellen, ob Iframes vorhanden sind, und zusätzlich in Firefox, ob sie in einem der Iframes ausgeführt wird.
quelle
document.defaultView.self === document.defaultView.top
oderwindow !== window.top
. Im Inhaltsskript des Firefox-Add-On-SDK ist das globaleself
Objekt ein Objekt, das zur Kommunikation mit dem Hauptskript verwendet wird.Ich bin nicht sicher, wie dieses Beispiel für ältere Webbrowser funktioniert, aber ich verwende es für IE, Firefox und Chrome ohne und ohne Probleme:
quelle
!(window===window.parent)
Ich benutze dies:
quelle
.indexOf("HTMLIFrameElement")
?Verwenden Sie diese Javascript-Funktion als Beispiel, um dies zu erreichen.
quelle
Das derzeit beste Legacy-Browser-Frame-Breaking-Skript
Die anderen Lösungen haben bei mir nicht funktioniert. Dieser funktioniert in allen Browsern:
Eine Möglichkeit, sich gegen Clickjacking zu verteidigen, besteht darin, auf jeder Seite ein "Frame-Breaker" -Skript einzufügen, das nicht eingerahmt werden sollte. Die folgende Methode verhindert, dass eine Webseite auch in älteren Browsern eingerahmt wird, die den X-Frame-Options-Header nicht unterstützen.
Fügen Sie im Dokument HEAD-Element Folgendes hinzu:
Wenden Sie zuerst eine ID auf das Stilelement selbst an:
Auf diese Weise kann sich alles im Dokument HEAD befinden und Sie benötigen nur eine Methode / Taglib in Ihrer API.
Referenz: https://www.codemagi.com/blog/post/194
quelle
quelle
Da Sie im Kontext einer Facebook-App nachfragen, sollten Sie dies möglicherweise auf dem Server erkennen, wenn die erste Anforderung gestellt wird. Facebook gibt eine Reihe von Querystring-Daten weiter, einschließlich des Schlüssels fb_sig_user, wenn dieser von einem Iframe aufgerufen wird.
Da Sie diese Daten wahrscheinlich ohnehin in Ihrer App überprüfen und verwenden müssen, bestimmen Sie damit den geeigneten Kontext für das Rendern.
quelle
Eigentlich habe ich window.parent überprüft und es hat bei mir funktioniert, aber in letzter Zeit ist window ein zyklisches Objekt und hat immer einen übergeordneten Schlüssel, einen Iframe oder keinen Iframe.
Wie aus den Kommentaren hervorgeht, funktioniert der Vergleich mit window.parent schwierig. Ich bin mir nicht sicher, ob dies funktioniert, wenn iframe genau dieselbe Webseite wie das übergeordnete ist.
quelle
window.parent === window
ist wahr. Ihre Antwort ist also falsch. Und dieser Vergleich könnte zur Überprüfung verwendet werden (zumindest in Chrom, nicht in einem anderen Browser getestet).Es ist ein uralter Code, den ich einige Male verwendet habe:
quelle
(parent.location == self.location)
parent.location
. Andernfalls wird eine Ausnahme ausgelöstWenn Sie wissen möchten, ob der Benutzer über die Registerkarte "Facebook-Seite" oder "Canvas" auf Ihre App zugreift, suchen Sie nach der signierten Anforderung. Wenn Sie es nicht bekommen, greift der Benutzer wahrscheinlich nicht über Facebook zu. Um sicherzustellen, bestätigen Sie die Struktur der signierten_Anforderungsfelder und den Inhalt der Felder.
Mit dem php-sdk können Sie die signierte Anfrage wie folgt erhalten:
Weitere Informationen zu Signed Request finden Sie hier:
https://developers.facebook.com/docs/reference/php/facebook-getSignedRequest/
und hier:
https://developers.facebook.com/docs/reference/login/signed-request/
quelle
Dies war für mich die einfachste Lösung.
quelle
Aber nur, wenn sich die Anzahl der Iframes auf Ihrer Seite und der Seite, die Sie in Iframe laden, unterscheidet. Machen Sie keinen Iframe auf Ihrer Seite, um eine 100% ige Garantie für das Ergebnis dieses Codes zu erhalten
quelle
Schreiben Sie dieses Javascript auf jede Seite
Dann wird automatisch zur Startseite weitergeleitet.
quelle