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

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

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

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


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

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


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


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

8 ответов


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

window.self !== window.top

Если вы IFramed, то ваш реферер-это Ваш url-адрес родительского фрейма.

document.referrer

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


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

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

console.log(isCrossOriginFrame());

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

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


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


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

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

однако это будет регистрировать сообщение об ошибке на консоли.


попробуйте это (в 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>

Если я вижу ваш вариант использования:

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

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

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


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

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);
}

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


для вложенных 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;
            }