Почему прерыватели кадров работают в разных областях, и можно ли условно использовать прерыватели кадров?
Я недавно исследовал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, но только если она находится в том же домене, что и ее родитель (или в настроенном допустимом домене) . Однако, по-видимому, это невозможно определить. это, поскольку та же самая политика происхождения запрещает мне доступ к местоположению родителя.
Итак, у меня есть два вопроса, в основном:
-
Почему вышеприведенный код прерывателя кадров вообще работает?
-
Существует ли какой-либо способ разбить фреймы условно, или единственная проверка, которую можно сделать, - это ли
top !== self
? (В частности, я хочу иметь возможность читать домен, так что я могу предоставить список допустимых доменов; просто проверка, нахожусь ли я в том же домене или нет, не будет идеальный.)
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" это ваш домен.