Как запретить IFRAME перенаправлять окно верхнего уровня

133

На некоторых веб-сайтах есть код для «выхода» из IFRAMEвложений, что означает, что если страница Aзагружается как IFRAMEвнутренняя родительская страница, Pкакой-то Javascript Aперенаправляет внешнее окно на A.

Обычно этот Javascript выглядит примерно так:

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

Мой вопрос: как я как автор родительской страницы Pи не являюсь автором внутренней страницы A, как я могу предотвратить Aэтот разрыв?

PS Мне кажется, это должно быть нарушение межсайтовой безопасности, но это не так.

Джейсон Коэн
источник
Я не думаю, что вы вообще многое можете сделать ... если вы не являетесь автором содержимого фрейма.
scunliffe

Ответы:

43

Попробуйте использовать свойство onbeforeunload, которое позволит пользователю выбрать, хочет ли он уйти со страницы.

Пример: https://developer.mozilla.org/en-US/docs/Web/API/Window.onbeforeunload

В HTML5 вы можете использовать свойство песочницы. См. Ответ Панкрата ниже. http://www.html5rocks.com/en/tutorials/security/sandboxed-iframes/

fasih.rana
источник
1
Тем не менее iFrames допускают междоменное взаимодействие с использованием postMessage. Это не угроза безопасности, но кому-то может быть интересно узнать, что эта возможность существует, когда они увидят ваш комментарий. :)
coreyward
На момент написания этого ответа это было невозможно. Спасибо за указание на это.
fasih.rana
@SirDarius, не могли бы вы показать пример, очень признателен.
user198989 03
Пользователь не будет знать, почему появляется это подтверждение, и, вероятно, выберет случайный ответ. Не рекомендую его использовать. Есть и другие решения - расширение sandbox.
Ориадам
1
@ fasih.rana Вторая статья мне очень помогла. Спасибо;)
MrD
127

В HTML5 был добавлен атрибут песочницы iframe . На момент написания это работает в Chrome, Safari, Firefox и последних версиях IE и Opera, но делает в значительной степени то, что вы хотите:

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

Если вы хотите разрешить перенаправление верхнего уровня, укажите sandbox="allow-top-navigation".

Панкрат
источник
чего ждать? Они позволили тебе это сделать? Я думал, что если веб-сайт захочет выйти из строя, все браузеры это позволят. Как люди должны уберечь свой сайт от фреймов из-за этого? Я не жалуюсь, круто.
Фаржер 06
3
Вот противоядие: blogs.msdn.com/b/ieinternals/archive/2010/03/30/...
Панкрат
1
@StephenSarcsamKamenar Если вы хотите защитить свой сайт от отображения в iframe, доступен заголовок X-Frame-Options со значением SAMEORIGIN . Большинство современных браузеров не отображают сайт в iframe с этим заголовком.
Grzegorz
4
К сожалению sandbox, не позволяет Flash или любой другой тип объекта в изолированном фрейме, что делает эту sandboxфункцию во многих случаях бесполезной.
oriadam
1
Веб-сайты не должны «вырываться» из протеста против включения в iframe. Они могут просто показать сообщение или остаться пустым. К сожалению, разрешение запуска скриптов в iframe по-прежнему открывает вас для мошеннического iframe, выполняющего while (1) {} и другие бесконечные циклы. Я хочу, чтобы каждый iframe мог иметь свой собственный поток.
Грегори Магаршак
51

Я использую sandbox = "..."

  • allow-forms позволяет отправлять формы
  • allow-popups разрешает всплывающие окна
  • allow-pointer-lock разрешает блокировку указателя
  • allow-same-origin позволяет документу сохранять свое происхождение
  • allow-scripts позволяет выполнять JavaScript, а также позволяет функциям запускаться автоматически
  • allow-top-navigation позволяет документу выйти за пределы рамки, перемещаясь по окну верхнего уровня

Верхняя навигация - это то, что вы хотите предотвратить, так что оставьте это, и это будет запрещено. Все, что не указано, будет заблокировано

ех.

        <iframe sandbox="allow-same-origin allow-scripts allow-popups allow-forms" src="http://www.example.com"</iframe>
adigioia
источник
3
Обратите внимание, что Flash (и любые другие объекты) также будут заблокированы без возможности разрешения этого. Эта «функция безопасности» не позволяет мне использовать песочницу целиком
oriadam
8

После прочтения спецификации w3.org . Я нашел свойство песочницы.

Вы можете установить sandbox="", что предотвращает перенаправление iframe. При этом он также не будет перенаправлять iframe. Вы потеряете щелчок по существу.

Пример здесь: http://jsfiddle.net/ppkzS/1/
Пример без песочницы: http://jsfiddle.net/ppkzS/

Parris
источник
4

Я знаю, что вопрос был задан давно, но вот моя улучшенная версия, она будет ждать 500 мс для любого последующего вызова только тогда, когда загружен iframe.

<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>

и onload="frameLoad()"и onreadystatechange="frameLoad();"должны быть добавлены к раме или фрейма.

Луис Делеон
источник
3

Я нашел несколько полезных советов по этому поводу:

Используя JS, как я могу остановить перенаправление дочерних фреймов iframe или, по крайней мере, уведомить пользователей о перенаправлении

http://www.codinghorror.com/blog/2009/06/we-done-been-framed.html

http://coderrr.wordpress.com/2009/02/13/preventing-frame-busting-and-click-jacking-ui-redressing/

артур
источник
2

Так как страница, которую вы загружаете внутри iframe, может выполнять код «разрыва» с помощью setInterval, onbeforeunload может оказаться не таким практичным, поскольку он может запутать пользователя вопросом «Вы уверены, что хотите уйти?» Диалоги.

Также есть атрибут безопасности iframe, который работает только в IE и Opera.

:(

user47087
источник
2

В моем случае я хочу, чтобы пользователь посетил внутреннюю страницу, чтобы сервер видел их IP-адрес как посетителя. Если я использую технику прокси-сервера php, я думаю, что внутренняя страница будет видеть мой IP-адрес сервера как посетителя, поэтому это не очень хорошо. Единственное решение, которое я получил до сих пор, - это Wilth onbeforeunload. Поместите это на свою страницу:

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

Это работает как в firefox, так и в том, что я тестировал. вы найдете версии, использующие что-то вроде evt.return (что угодно) дерьмо ... которое не работает в firefox.

Radu
источник
0

Таким образом вы сможете контролировать любое действие на странице во фрейме, чего вы не можете. Применяется политика происхождения одного домена .

Диодей - Джеймс Макфарлейн
источник
20
Я не прошу контролировать то, что находится внутри IFRAME. Я прошу , чтобы предотвратить то , что внутри IFRAME от контроля со мной.
Джейсон Коэн,