Почему прерыватели кадров работают в разных областях, и можно ли условно использовать прерыватели кадров?


Я недавно исследовалFrame breaking код и столкнулся с некоторым действительно странным поведением, связанным стой же политикой origins , которую мне трудно понять.

Предположим, у меня есть прерыватель страниц.HTML на домен, и контейнер страницы.HTML на домен Б. пример кода рамы выключателя пойдет на выключатель.html, как показано ниже:

if (top !== self) top.location.href = self.location.href;

Это успешно сломает прерыватель.html из контейнера.html, но я не понимаю, почему это должен. Из моего чтения той же политики происхождения, top.location не должно быть доступно вообще, так как контейнер.html находится в другом домене, чем Breaker.формат html. Еще более странным кажется этот топ.расположение только для записи :

// Fails if Container.html is on a different domain than Breaker.html
alert(top.location);

Это проблематично для меня, потому что я пытаюсь написать код, который позволяет моей странице быть в iframe, но только если она находится в том же домене, что и ее родитель (или в настроенном допустимом домене) . Однако, по-видимому, это невозможно определить. это, поскольку та же самая политика происхождения запрещает мне доступ к местоположению родителя.

Итак, у меня есть два вопроса, в основном:

  1. Почему вышеприведенный код прерывателя кадров вообще работает?

  2. Существует ли какой-либо способ разбить фреймы условно, или единственная проверка, которую можно сделать, - это ли top !== self? (В частности, я хочу иметь возможность читать домен, так что я могу предоставить список допустимых доменов; просто проверка, нахожусь ли я в том же домене или нет, не будет идеальный.)

3 10

3 ответа:

Для вашего ответа на вопрос № 1: с точки зрения безопасности существует большая разница между доступом на чтение и доступом на запись. Умение читать сверху.местоположение.хреф-это проблема безопасности. Возможность писать сверху.местоположение.хреф-нет.

Что касается ответа на ваш вопрос, я не знаю javascript достаточно хорошо, чтобы быть уверенным, но одна идея состоит в том, чтобы предположить, что если читать сверху.расположение не удается (проверьте наличие исключений), оно находится в другом домене.

Ответ на вопрос 1 состоит в том, что оператор равенства может быть использован против top.местоположение.хреф по наследственным причинам. Выключатель.html не может читать сверху.местоположение.но он может сравнить его с другим значением.

Ответ на вопрос 2 тогда становится Нет, вы должны использовать != = расстаться, потому что вы не сможете сделать подстроку сверху.местоположение.href от кросс-доменного взломщика.формат html.

Я могу ошибаться, но это мое понимание текущего мира iframe.

Это для вопроса номер 2: Если вы хотите взять HREF родителя.расположение (не сверху.местоположение), вы можете сделать это:

if ((window.top === window.parent) && (history.length==1)) parentHREF=document.referrer;

В основном этот код делает следующее::
[1] проверка, является ли Родительский кадр верхним, потому что вы можете взять только родительский HREF, даже если он не является верхним кадром.
[2] проверка, была ли история iframe пустой перед загрузкой ее источника, потому что если нет... документ.реферер вернет последний HREF в истории этого фрейма.

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

if ([location.hostname, 'stackoverflow.com'].indexOf(location.hostname)>=0) hasToBeOpened=true;

Обратите внимание, что вы еще один вариант: можете использовать целевую страницу, чтобы проверить, должна ли открываться "первая" страница или нет, используйте этот код:

<head>
<script>
var parentHREF;
if ((window.top === window.parent) && (history.length==1)) parentHREF=document.referrer;
if (/*conditions mentiones above*/) document.write("<META http-equiv='refresh' content='0;URL=http://example.com/go-here.html'>");
</script>
</head>

Делая это таким образом, "первая" страница заменит первое (в данном случае это первое) значение истории. Этот код предполагали "example.com" это ваш домен.