Подтвердить что ты не робот

Неверный способ определить, включена ли эта страница в межсетевом iframe

Ответ на Неверный способ обнаружения iframe - это перекрестный домен" описывает метод проверки if iframe на страницах страницы на одну и ту же доменную или междоменную страницу, работая с интерпретаторами различных междоменных политик браузеров и избегая сообщений об ошибках, которые могут прерывать пользователя или останавливать javascript.

Я хочу сделать эквивалент этого, но с дочерней страницы внутри проверки iframe, находится ли он внутри междоменного iframe или нет.

Это возможно для доступа (того же домена) информации о родительском с помощью parent global, например. parent.document.location, но существует ли надежный способ сделать этот кросс-браузер без сбоев в ошибках, когда он обнаруживает, что родительский объект является междоменным?


Для удобного тестирования здесь jsbin внутри jsfiddle, который попадает в ошибку при попытке проверить, доступен ли parent.location.host. Есть ли надежный способ получить что-то полезное, например false, говорящее нам, что это кросс-доменный родитель, а не ошибка?

Есть ли вариант try...catch, который будет надежным кросс-браузером? Или, может быть, какой-то умный трюк с использованием возвращаемого значения от parent.postMessage()? (хотя родительская страница не может быть отредактирована)


Случай использования: представляйте встраиваемый контент, который должен быть встроен на страницы на своем собственном сайте, и третьими лицами. Если страница находится в одном домене iframe, мы скрываем брендинг и ссылки на исходный сайт, потому что пользователь уже здесь. Если они обращаются к странице с стороннего iframe или загружают страницу напрямую, мы показываем брендинг и кредиты, чтобы они могли видеть источник контента.


Чтобы уточнить, я знаю о политике одного домена, и мне все равно, что такое домен перекрестного браузера, я просто хочу написать простое, но надежное условие if вроде if( crossDomainParent() ){ /* do something */}

4b9b3361

Ответ 1

Сначала проверьте, есть ли IFramed.

window.self !== window.top

Если вы IFramed, то ваш реферер является вашим родительским фреймворком.

document.referrer

Из этого URL-адреса вы сможете определить, хотите ли вы разветкить свой код.

Ответ 2

Реальное кросс-браузерное решение для потомков:

function isCrossOriginFrame() {
  try {
    return (!window.top.location.hostname);
  } catch (e) {
    return true;
  }
}

console.log(isCrossOriginFrame());

Протестировано на достойном уровне рабочего стола и мобильных браузеров.

https://jsfiddle.net/arzd4btc/3/

Ответ 3

используйте заголовок x-frame, это предотвратит загрузку вашего сайта в frame/iframe. существуют различные варианты здесь читать

Ответ 4

Если я вижу ваш прецедент:

Я бы посмотрел его на стороне сервера (кто назвал ваш сайт), используя $_SERVER['REMOTE_ADDR'], и если это ваш IP-адрес, вы можете скрыть брендинг и ссылки.

Если прецедент предотвратит создание вашего сайта, вы можете использовать X-Frame-Options: deny.

Другое предположение: Элементы внутри документа имеют свойство ownerDocument, возможно, это может помочь определить, что вы хотите.

Ответ 5

В соответствии с вашими текущими ограничениями нет возможности достичь этого с помощью DOM API. Любая оценка с окном, принадлежащим другому домену, выведет ошибку.

Тем не менее, "хак" должен был отправить XHR из вашего дочернего окна, чтобы загрузить известную страницу в вашем домене. Если этот XHR завершится успешно, то вы знаете, что оба окна являются одним и тем же доменом.

Однако это приведет к регистрации сообщения об ошибке на консоли.

Ответ 6

Попробуйте это (в iframe)

<script type="text/javascript">
  var detectOrigin = (window.location.ancestorOrigins === undefined ? 
  /example.com/.test(document.domain) /* firefox */ : 
  /example.com/.test(window.location.ancestorOrigins[0])); /* webkit */
  if (detectOrigin === true) {console.log(detectOrigin)}; /* `true` example.com origin */
  if (detectOrigin === false) {console.log(detectOrigin)}; /* `false` !example.com origin */
</script>

Ответ 7

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

function IsCrossDomainFrame() {
    if( parent === window ) return false; //not a frame
    var parentLocation = new URL(document.referer);//the referer of an iframe is the parent
    return (parentLocation.protocol !== location.protocol ||
            parentLocation.hostname !== location.hostname ||
            parentLocation.port     !== location.port);
}

Протокол, имя хоста и порт определяют кросс-домен.

Ответ 8

Для вложенных iframes: рекурсивный способ узнать, является ли iframe (где этот код выполняется) является кросс-доменом или нет:

function crosDomIfrm(win, data) {
        data = (typeof data === 'undefined')?{ref:win.document.location,isCD:false}:data;
        try { 
            if( win.document.referrer != '' ){
                data.isCD = parseURL(data.ref) != parseURL(win.document.referrer);
            }
        } catch(e){}
        if ( (win.self !== win.parent) && !data.isCD ) { //I'm in iframe
            data = crosDomIfrm( win.parent, data );
        }
        return {ref:data.ref,isCD:data.isCD};
    },

function parseURL(url) {
                var a=document.createElement('a');
                a.href=url;
                return a.hostname;
            }