web-dev-qa-db-fra.com

Comment empêcher IFRAME de rediriger la fenêtre de niveau supérieur

Certains sites Web ont du code pour "sortir" des IFRAME enceintes, ce qui signifie que si une page A est chargée en tant que IFRAME dans une page parente P quelque Javascript dans A redirige la fenêtre externe vers A.

Typiquement ce Javascript ressemble à quelque chose comme ça:

<script type="text/javascript">
  if (top.location.href != self.location.href)
     top.location.href = self.location.href;
</script>

Ma question est la suivante: en tant qu'auteur de la page parent P et n'étant pas l'auteur de la page intérieure A, comment puis-je empêcher A de faire cette rupture?

P.S. Il me semble que cela devrait être une violation de sécurité entre sites, mais ce n’est pas le cas.

121
Jason Cohen

Essayez d’utiliser la propriété onbeforeunload, qui permettra à l’utilisateur de choisir s’il souhaite naviguer hors de la page.

Exemple: https://developer.mozilla.org/en-US/docs/Web/API/Window.onbeforeunload

En HTML5, vous pouvez utiliser la propriété sandbox. Veuillez voir la réponse de Pankrat ci-dessous. http://www.html5rocks.com/en/tutorials/security/sandboxed-iframes/

40
fasih.rana

Avec HTML5, l’attribut iframe sandbox a été ajouté. Au moment de la rédaction de cet article fonctionne sur Chrome, Safari, Firefox et les versions récentes de IE et Opera mais fait à peu près ce que vous voulez:

<iframe src="url" sandbox="allow-forms allow-scripts"></iframe>

Si vous souhaitez autoriser les redirections de niveau supérieur, spécifiez sandbox="allow-top-navigation".

120
Pankrat

J'utilise sandbox = "..."

  • permettre-formes permet la soumission de formulaire
  • allow-popups permet les popups
  • allow-pointeur-lock permet le blocage d'un pointeur
  • allow-same-Origin permet au document de conserver son origine
  • allow-scripts permet l'exécution de JavaScript et permet également aux fonctionnalités de se déclencher automatiquement
  • allow-top-navigation permet au document de sortir du cadre en naviguant dans la fenêtre du niveau supérieur

La navigation du haut est ce que vous voulez empêcher, alors laissez cela de côté et cela ne sera pas autorisé. Tout ce qui restera sera bloqué

ex.

        <iframe sandbox="allow-same-Origin allow-scripts allow-popups allow-forms" src="http://www.example.com"</iframe>
42
adigioia

Après avoir lu le w3.org spec . J'ai trouvé la propriété sandbox.

Vous pouvez définir sandbox="", qui empêche l'iframe de rediriger. Cela étant dit, l'iframe ne sera pas redirigé non plus. Vous allez perdre le clic essentiellement.

Exemple ici: http://jsfiddle.net/ppkzS/1/
Exemple sans bac à sable: http://jsfiddle.net/ppkzS/

7
Parris

Je sais que cela fait longtemps que la question n’a pas été posée, mais voici ma version améliorée, elle attendra 500 ms pour tout appel suivant uniquement lorsque l’iframe est chargé.

<script type="text/javasript">
var prevent_bust = false ;
    var from_loading_204 = false;
    var frame_loading = false;
    var prevent_bust_timer = 0;
    var  primer = true;
    window.onbeforeunload = function(event) {
        prevent_bust = !from_loading_204 && frame_loading;
        if(from_loading_204)from_loading_204 = false;
        if(prevent_bust){
            prevent_bust_timer=500;
        }
    }
    function frameLoad(){
        if(!primer){
            from_loading_204 = true;
            window.top.location = '/?204';
            prevent_bust = false;
            frame_loading = true;
            prevent_bust_timer=1000;
        }else{
            primer = false;
        }
    }
    setInterval(function() {  
        if (prevent_bust_timer>0) {  
            if(prevent_bust){
                from_loading_204 = true;
                window.top.location = '/?204';
                prevent_bust = false;
            }else if(prevent_bust_timer == 1){
                frame_loading = false;
                prevent_bust = false;
                from_loading_204 = false;
                prevent_bust_timer == 0;
            }



        }
        prevent_bust_timer--;
        if(prevent_bust_timer==-100) {
            prevent_bust_timer = 0;
        }
    }, 1);
</script>

et onload="frameLoad()" et onreadystatechange="frameLoad();" doivent être ajoutés au cadre ou à l'iframe.

4
Luis Deleon
3
artur

Dans mon cas, je veux que l'utilisateur visite la page intérieure afin que le serveur voit son adresse IP en tant que visiteur. Si j'utilise la technique du proxy php, je pense que la page intérieure verra l'adresse IP de mon serveur en tant que visiteur, donc ce n'est pas bien. La seule solution que j’ai eu jusqu’à présent est de se décharger. Mettez ceci sur votre page:

<script type="text/javascript">
    window.onbeforeunload = function () {                       
         return "This will end your session";
    }
</script>

Cela fonctionne à la fois dans Firefox et c'est-à-dire que c'est ce que j'ai testé. vous trouverez des versions utilisant quelque chose comme evt.retour (peu importe) de merde ... qui ne fonctionne pas dans Firefox.

2
radu

Etant donné que la page que vous chargez dans l'iframe peut exécuter le code "break out" avec setInterval, onbeforeunload risque de ne pas être aussi pratique que cela, car elle pourrait donner à l'utilisateur le mot "Êtes-vous sûr de vouloir partir?" dialogues.

Il y a aussi l'attribut de sécurité iframe qui ne fonctionne que sur IE & Opera

:(

2
user47087

Ainsi, vous pourrez contrôler n'importe quelle action de la page encadrée, ce que vous ne pouvez pas. Politique d'origine du même domaine s'applique.