Ik ben het schrijven van een iframe gebaseerd facebook app. Nu wil ik hetzelfde html-pagina te gebruiken om de normale website, alsmede het doek pagina binnen facebook te maken. Ik wil weten of ik kan bepalen of de pagina in de iframe of direct in de browser is geladen?
Hoe te identificeren wanneer een webpagina wordt binnen een iframe of direct in het browservenster wordt geladen?
Browsers kunnen toegang te blokkeren tot window.topwijten aan dezelfde oorsprong beleid . IE bugs vinden ook plaats. Hier is de werkende code:
function inIframe () {
try {
return window.self !== window.top;
} catch (e) {
return true;
}
}
topen selfzijn beide windowobjecten (samen met parent), dus je ziet als je window is het bovenste venster.
RoBorg is correct, maar ik wilde een kanttekening toe te voegen.
In IE7 / IE8 wanneer Microsoft Tabs om hun browser toegevoegd ze brak een ding dat ravage zal worden met uw JS als je niet voorzichtig bent.
Stel je voor pagina-indeling:
MainPage.html
IframedPage1.html (named "foo")
IframedPage2.html (named "bar")
IframedPage3.html (named "baz")
Nu in frame "baz" u op een koppeling (geen doel, belastingen in de "baz" kader) het werkt prima.
Als de pagina die wordt geladen, laat noemen special.html, maakt gebruik van JS om te controleren of "het" heeft een bovenliggende frame genaamd "bar" het zal return true (verwacht).
Laten we nu zeggen dat de special.html pagina wanneer het laadt, controleert de bovenliggende frame (voor het bestaan en de naam, en als het "bar" Het laadt zichzelf in de bar frame. bv
if(window.parent && window.parent.name == 'bar'){
window.parent.location = self.location;
}
So far so good. Nu komt de bug.
Laten we zeggen in plaats van te klikken op de originele link als normaal, en het laden van de special.html pagina in de "baz" frame, je middelbare geklikt of ervoor gekozen om het in een nieuw tabblad te openen.
Wanneer die nieuw tabblad belastingen ( waarbij geen enkele oorspronkelijke frames at all! ) IE zal een eindeloze lus van laden van pagina's in te voeren! omdat IE "kopieën op" de frameconstructie in JavaScript, zodat het nieuwe tabblad heeft wel een ouder, en die ouder de naam "bar".
Het goede nieuws is dat het controleren:
if(self == top){
//this returns true!
}
in die nieuwe tabblad wordt return true, en daarom kun je testen op deze vreemde aandoening.
Aangezien u vraagt in de context van een Facebook-app, wilt u misschien overwegen het opsporen van deze op de server wanneer het oorspronkelijke verzoek wordt gedaan. Facebook passeert langs een bos van querystring gegevens, inclusief de fb_sig_user toets als het wordt aangeroepen vanuit een iframe.
Omdat je waarschijnlijk moeten controleren en hoe dan ook deze gegevens gebruiken in uw app, gebruik deze om de de juiste context te bepalen te maken.
Gebruik deze javascript functie als een voorbeeld van hoe om dit te bereiken.
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;
}
De geaccepteerde antwoord werkte niet voor me in de inhoud script van een Firefox 6.0 Extension (Addon-SDK 1.0): Firefox voert de inhoud script in elkaar: de top-level-venster en in alle iframes.
Binnen de inhoud script krijg ik de volgende resultaten:
(window !== window.top) : false
(window.self !== window.top) : true
Het vreemde van deze uitgang is dat het is altijd hetzelfde, ongeacht of de code wordt uitgevoerd binnen een iframe of in het venster op het hoogste niveau.
Aan de andere kant lijkt Google Chrome mijn inhoud script slechts één keer uit te voeren binnen het venster op het hoogste niveau, dus het zou bovenstaande helemaal niet werken.
Wat uiteindelijk werkte voor mij in een content script in beide browsers is dit:
console.log(window.frames.length + ':' + parent.frames.length);
Zonder iframes deze drukken 0:0in een top-level venster met een raster wordt afgedrukt 1:1, en de enige iframe van een document wordt afgedrukt 0:1.
Dit maakt mijn extensie om te bepalen in beide browsers als er geen iframes aanwezig, en bovendien, in Firefox als het wordt uitgevoerd in een van de iframes.
Het is een oud stukje code dat ik een paar keer hebt gebruikt:
if (parent.location.href == self.location.href) {
window.location.href = 'https://www.facebook.com/pagename?v=app_1357902468';
}
Ik doe dit met behulp van:
var isIframe = (self.frameElement && (self.frameElement+"").indexOf("HTMLIFrameElement") > -1);
if (window.frames.length != parent.frames.length) { page loaded in iframe }
Maar alleen als het aantal iframes verschilt in uw pagina en pagina die laadt u in iframe. Laat er geen iframe in uw pagina naar 100% garantie van het resultaat van deze code hebben
Schrijf dit javascript in elke pagina
if (self == top)
{ window.location = "Home.aspx"; }
Dan zal het automatisch omleidingen naar de homepage.
Als u wilt weten of de gebruiker toegang heeft tot uw app op het tabblad facebook pagina of canvas cheque voor de ondertekende aanvraag. Als u het niet krijgt, waarschijnlijk de gebruiker niet de toegang van Facebook. Om ervoor te zorgen bevestigen maken het signed_request velden structuur en velden inhoud.
Met de php-sdk kunt u de ondertekende aanvraag als dit te krijgen:
$signed_request = $facebook->getSignedRequest();
U kunt meer over ondertekend verzoek hier te lezen:
https://developers.facebook.com/docs/reference/php/facebook-getSignedRequest/
en hier:
https://developers.facebook.com/docs/reference/login/signed-request/
window.frameElementGeeft het element (bijvoorbeeld <iframe> of <object>) waarin het venster is ingebed, of null als het venster hoogste niveau. Dus identificerende code eruit ziet
if (window.frameElement) {
// in frame
}
else {
// not in frame
}
Dit is standaard en vrij nieuwe methode. Het werkt precies in Chrome en Firefox. Ik kan het niet aanraden als universele oplossing, maar het moet hier worden vermeld denk ik.
Ik heb eigenlijk gebruikt om te window.parent controleren en het werkte voor mij, maar de laatste tijd venster is een cyclisch object en heeft altijd een bovenliggende sleutel, iframe of geen iframe.
Omdat de respondenten stelt moeilijk te vergelijken met window.parent werken. Niet zeker of dit zal werken als iframe is precies dezelfde webpagina als ouder.
window === window.parent;
Ik ben niet zeker hoe dit voorbeeld werkt voor oudere webbrowsers, maar ik gebruik dit voor IE, Firefox en Chrome zonder en probleem:
var iFrameDetection = (window === window.parent) ? false : true;
Best-for-now Legacy Browser Frame Breaking Script
De andere oplossingen niet gewerkt voor mij. Deze werkt op alle browsers:
Een manier om te verdedigen tegen clickjacking is om een "kader-breaker" script op elke pagina die niet mogen worden ingelijst bevatten. De volgende methode wordt een webpagina van wordt omlijst zelfs in oudere browsers, die geen ondersteuning van de X-Frame-Options-Header voorkomen.
In het document HEAD element, voeg de volgende:
<style id="antiClickjack">body{display:none !important;}</style>
Breng eerst een ID aan de stijl element zelf:
<script type="text/javascript">
if (self === top) {
var antiClickjack = document.getElementById("antiClickjack");
antiClickjack.parentNode.removeChild(antiClickjack);
} else {
top.location = self.location;
}
</script>
Op deze manier kan alles in het document HEAD en u hoeft slechts één methode / taglib in uw API.
Referentie: https://www.codemagi.com/blog/post/194
Dit uiteindelijk zijn de eenvoudigste oplossing voor mij.
<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>













