Je vous écris une application facebook basée iframe. Maintenant, je veux utiliser la même page html pour rendre le site normal ainsi que la page de la toile dans les facebook. Je veux savoir si je peux déterminer si la page a été chargé à l'intérieur de l'iframe ou directement dans le navigateur?
Comment identifier si une page Web est en cours de chargement à l'intérieur d'un iframe ou directement dans la fenêtre du navigateur?
Les navigateurs peuvent bloquer l' accès à en window.topraison de même politique d'origine . IE bogues ont également lieu. Voici le code de travail:
function inIframe () {
try {
return window.self !== window.top;
} catch (e) {
return true;
}
}
topet selfsont les deux windowobjets (ainsi que parent), de sorte que vous voyez si votre fenêtre est la fenêtre supérieure.
RoBorg est correct, mais je voulais ajouter une note de côté.
Dans IE7 / IE8 lorsque Microsoft a ajouté des onglets dans leur navigateur, ils ont cassé une chose qui provoque des ravages avec votre JS si vous ne faites pas attention.
Imaginez cette mise en page:
MainPage.html
IframedPage1.html (named "foo")
IframedPage2.html (named "bar")
IframedPage3.html (named "baz")
Maintenant, dans le cadre « baz » vous cliquez sur un lien (pas de cible, les charges dans le cadre « baz »), il fonctionne très bien.
Si la page qui est chargé, permet de l'appeler special.html, utilise JS pour vérifier si « il » a un cadre parent nommé « bar » il retourne vrai (prévu).
Maintenant, supposons que que la page special.html quand il charge, vérifie le cadre parent (pour l'existence et son nom, et si elle est « bar » il se recharge dans le cadre bar. par exemple
if(window.parent && window.parent.name == 'bar'){
window.parent.location = self.location;
}
Jusqu'ici tout va bien. Maintenant vient le bug.
Disons plutôt que de cliquer sur le lien d'origine comme d'habitude, et le chargement de la page special.html dans le cadre « baz », vous cliqué avec le bouton du milieu ou choisi de l'ouvrir dans un nouvel onglet.
Lorsque que les nouvelles charges de l' onglet ( sans images parent du tout! ) IE entrera dans une boucle sans fin de chargement de la page! parce que IE « copies sur » la structure de cadre en JavaScript de telle sorte que le nouvel onglet a un parent, et ce parent a le nom « bar ».
Les bonnes nouvelles, est que la vérification:
if(self == top){
//this returns true!
}
dans ce nouvel onglet ne retourne vrai, et donc vous pouvez tester cette condition étrange.
Puisque vous demandez dans le contexte d'une application Facebook, vous pouvez envisager de détecter ce serveur au moment de la demande initiale est faite. Facebook passera le long d'un tas de données querystring y compris la touche fb_sig_user si elle est appelée à partir d'un iframe.
Puisque vous avez probablement besoin de vérifier et utiliser ces données de toute façon dans votre application, utilisez pour déterminer le contexte approprié de rendre.
Utilisez cette fonction javascript comme un exemple sur la façon d'y parvenir.
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;
}
La réponse acceptée ne fonctionne pas pour moi à l'intérieur du script de contenu d'un Firefox 6.0 Extension (Addon-SDK 1.0): Firefox exécute le script contenu dans chaque: la fenêtre de haut niveau et dans tous les iframes.
A l'intérieur du script de contenu que je reçois les résultats suivants:
(window !== window.top) : false
(window.self !== window.top) : true
La chose étrange à propos de cette sortie est qu'il est toujours le même indépendamment du fait que le code est exécuté à l'intérieur d'un iframe ou la fenêtre de niveau supérieur.
D'autre part Google Chrome semble exécuter une seule fois mon script contenu dans la fenêtre de haut niveau, de sorte que le ne fonctionnerait pas au-dessus du tout.
Ce qui a finalement travaillé pour moi dans un script contenu dans les deux navigateurs est la suivante:
console.log(window.frames.length + ':' + parent.frames.length);
Sans iframes cette impression 0:0, dans une fenêtre de niveau supérieur contenant une image qu'il imprime 1:1, et dans le seul iframe d'un document qu'il imprime 0:1.
Cela permet à mon extension de déterminer dans les deux navigateurs s'il y a des iframes présents, et en plus dans Firefox s'il est exécuté dans l'un des iframes.
Il est un ancien morceau de code que je l'ai utilisé plusieurs fois:
if (parent.location.href == self.location.href) {
window.location.href = 'https://www.facebook.com/pagename?v=app_1357902468';
}
J'utilise ceci:
var isIframe = (self.frameElement && (self.frameElement+"").indexOf("HTMLIFrameElement") > -1);
if (window.frames.length != parent.frames.length) { page loaded in iframe }
Mais seulement si le nombre de iframes diffère dans la page et la page qui vous chargement dans une iframe. Ne vous iframe dans votre page pour avoir 100% garantie de résultat de ce code
Notez ce javascript sur chaque page
if (self == top)
{ window.location = "Home.aspx"; }
Ensuite, il redirige automatiquement vers la page d'accueil.
Si vous voulez savoir si l'utilisateur accède à votre application de l'onglet de la page facebook ou chèque de toile pour la demande signée. Si vous ne l'obtenez pas, sans doute l'utilisateur n'accède pas à Facebook. Pour confirmer que la structure des champs signed_request et champs contenu.
Avec le php-sdk vous pouvez obtenir la demande signée comme ceci:
$signed_request = $facebook->getSignedRequest();
Vous pouvez en savoir plus sur demande Signé ici:
https://developers.facebook.com/docs/reference/php/facebook-getSignedRequest/
et ici:
https://developers.facebook.com/docs/reference/login/signed-request/
window.frameElementRenvoie l'élément (par exemple <iframe> ou <object>) dans laquelle la fenêtre est intégrée, ou une valeur nulle si la fenêtre est de niveau supérieur. Donc, code d'identification ressemble
if (window.frameElement) {
// in frame
}
else {
// not in frame
}
Ce standard et plutôt nouvelle méthode. Il fonctionne exactement dans Chrome et Firefox. Je ne peux pas le recommander comme solution universelle , mais il faut mentionner ici que je pense.
En fait, je l'habitude de vérifier window.parent et cela a fonctionné pour moi, mais ces derniers temps la fenêtre est un objet cyclique et a toujours une clé parente, iframe ou pas iframe.
Comme les commentaires suggèrent la comparaison difficile avec des œuvres window.parent. Je ne sais pas si cela fonctionnera si iframe est exactement la même page Web en tant que parent.
window === window.parent;
Je ne sais pas comment cet exemple fonctionne pour les navigateurs Web plus anciens mais j'utilise ceci pour IE, Firefox et Chrome sans problème et:
var iFrameDetection = (window === window.parent) ? false : true;
Best-pour-maintenant Cadre du navigateur Legacy Briser Script
Les autres solutions ne travaillaient pour moi. Celui-ci fonctionne sur tous les navigateurs:
Une façon de se défendre contre clickjacking est d'inclure un script « frame-breaker » dans chaque page qui ne devrait pas être encadrée. La méthodologie suivante empêchera une page Web d'être encadrée même dans les anciens navigateurs, qui ne prennent pas en charge le X-Frame-Options-tête.
Dans le document élément HEAD, ajouter ce qui suit:
<style id="antiClickjack">body{display:none !important;}</style>
Tout d'abord appliquer un ID à l'élément de style lui-même:
<script type="text/javascript">
if (self === top) {
var antiClickjack = document.getElementById("antiClickjack");
antiClickjack.parentNode.removeChild(antiClickjack);
} else {
top.location = self.location;
}
</script>
De cette façon, tout peut être dans le document HEAD et vous avez seulement besoin d'une méthode / taglib dans votre API.
Référence: https://www.codemagi.com/blog/post/194
Cela a fini d'être la solution la plus simple pour moi.
<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>













