web-dev-qa-db-fra.com

Existe-t-il un moyen côté client de détecter les options X-Frame?

Existe-t-il un bon moyen de détecter quand une page ne va pas s'afficher dans un cadre à cause de l'en-tête X-Frame-Options? Je sais que je peux demander la page côté serveur et rechercher l'en-tête, mais j'étais curieux de savoir si le navigateur dispose d'un mécanisme pour détecter cette erreur.

41
Newtang

OK, celui-ci est vieux mais toujours d'actualité.

Fait: Lorsqu'un iframe charge une URL qui est bloquée par une X-Frame-Options, le temps de chargement est très court.

Hack: Donc si l'onload se produit immédiatement, je sais que c'est probablement a X-Frame-Options problème.

Disclaimer: C'est probablement l'un des codes les plus "hacki" que j'ai écrit, alors ne vous attendez pas à grand chose:

var timepast=false; 
var iframe = document.createElement("iframe");

iframe.style.cssText = "position:fixed; top:0px; left:0px; bottom:0px; right:0px; width:100%; height:100%; border:none; margin:0; padding:0; overflow:hidden; z-index:999999;";
iframe.src = "http://pix.do"; // This will work
//iframe.src = "http://google.com"; // This won't work
iframe.id = "theFrame";

// If more then 500ms past that means a page is loading inside the iFrame
setTimeout(function() {
    timepast = true;
},500);

if (iframe.attachEvent){
    iframe.attachEvent("onload", function(){
    if(timepast) {
            console.log("It's PROBABLY OK");
        }
        else {
            console.log("It's PROBABLY NOT OK");
        }
    });
} 
else {
    iframe.onload = function(){
        if(timepast) {
            console.log("It's PROBABLY OK");
        }
        else {
            console.log("It's PROBABLY NOT OK");
        }
    };
}
document.body.appendChild(iframe);
12
Iftach

Avertissement: cette réponse que j'ai écrite en 2012 (Chrome était la version ~ 20 à l'époque) est obsolète et je la garderai ici à des fins historiques uniquement. Lisez et utilisez à vos risques et périls.


D'accord, c'est une question un peu ancienne, mais voici ce que j'ai découvert (ce n'est pas une réponse complète) pour Chrome/Chrome.

la façon de détecter si une trame pointant vers une adresse étrangère a été chargée est simplement d'essayer d'accéder à son contentWindow ou à son document.

voici le code que j'ai utilisé:

element.innerHTML = '<iframe class="innerPopupIframe" width="100%" height="100%" src="'+href+'"></iframe>';
myframe = $(element).find('iframe');

puis, plus tard:

try {
    var letstrythis = myframe.contentWindow;
} catch(ex) {
    alert('the frame has surely started loading');
}

le fait est que si les X-Frame-Options interdisent l'accès, alors myFrame.contentWindow sera accessible.

le problème ici est ce que j'ai appelé "alors, plus tard". Je n'ai pas encore compris sur quoi compter, quel événement souscrire pour trouver quel est le bon moment pour effectuer le test.

7
BiAiB

Ceci est basé sur la réponse de @ Iftach , mais est un peu moins hacky.

Il vérifie si iframe.contentWindow.length > 0 ce qui suggère que l'iframe a été chargé avec succès.

En outre, il vérifie si l'événement iframe onload s'est déclenché dans les 5 secondes et l'alerte également. Cela intercepte le chargement échoué du contenu mixte (d'une manière quoique hacky).

var iframeLoaded = false;
var iframe = document.createElement('iframe');

// ***** SWAP THE `iframe.src` VALUE BELOW FOR DIFFERENT RESULTS ***** //
// iframe.src = "https://davidsimpson.me"; // This will work
iframe.src = "https://google.com"; // This won't work

iframe.id = 'theFrame';
iframe.style.cssText = 'position:fixed; top:40px; left:10px; bottom:10px;'
 + 'right:10px; width:100%; height:100%; border:none; margin:0; padding:0; overflow:hidden; z-index:999999;';

var iframeOnloadEvent = function () {
    iframeLoaded = true;
  var consoleDiv = document.getElementById('console');
    if (iframe.contentWindow.length > 0) {
    consoleDiv.innerHTML = '✔ Content window loaded: ' + iframe.src;
    consoleDiv.style.cssText = 'color: green;'
    } else {
    consoleDiv.innerHTML = '✘ Content window failed to load: ' + iframe.src;
    consoleDiv.style.cssText = 'color: red;'
    }
} 

if (iframe.attachEvent){
    iframe.attachEvent('onload', iframeOnloadEvent);
} else {
    iframe.onload = iframeOnloadEvent;
}
document.body.appendChild(iframe);

// iframe.onload event doesn't trigger in firefox if loading mixed content (http iframe in https parent) and it is blocked.
setTimeout(function () {
    if (iframeLoaded === false) {
        console.error('%c✘ iframe failed to load within 5s', 'font-size: 2em;');
    consoleDiv.innerHTML = '✘ iframe failed to load within 5s: ' + iframe.src;
    consoleDiv.style.cssText = 'color: red;'    
  }
}, 5000);

Démonstration en direct ici - https://jsfiddle.net/dvdsmpsn/7qusz4q3/ - afin que vous puissiez la tester dans les navigateurs concernés.

Au moment de la rédaction, il fonctionne sur la version actuelle sur Chrome, Safari, Opera, Firefox, Vivaldi et Internet Explorer 11. Je ne l'ai pas testé dans d'autres navigateurs.

2
dvdsmpsn

Au moins dans Chrome, vous pouvez remarquer l'échec du chargement, car l'événement iframe.onload ne se déclenche pas. Vous pouvez l'utiliser comme indicateur que la page peut ne pas autoriser l'iframage.

0
apenwarr

Les outils de test en ligne peuvent être utiles. J'ai utilisé https://www.hurl.it/ . vous pouvez clairement voir l'en-tête de la réponse. Recherchez l'option X-frame. if value is deny - Il ne s'affichera pas dans iframe. même origine - uniquement à partir du même domaine, autoriser - permettra à partir de sites Web spécifiques.

Si vous voulez essayer un autre outil, vous pouvez simplement google pour "http request test online".

0
OlgaY

La seule chose à laquelle je peux penser est de proxy une demande AJAX pour l'url, puis regardez les en-têtes, et si elle n'a pas X-Frame-Options, puis affichez-la dans le loin d'être idéal, mais mieux que rien.

0
Newtang