Ответ 1
Сначала проверьте, есть ли IFramed.
window.self !== window.top
Если вы IFramed, то ваш реферер является вашим родительским фреймворком.
document.referrer
Из этого URL-адреса вы сможете определить, хотите ли вы разветкить свой код.
Ответ на Неверный способ обнаружения 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 */}
Сначала проверьте, есть ли IFramed.
window.self !== window.top
Если вы IFramed, то ваш реферер является вашим родительским фреймворком.
document.referrer
Из этого URL-адреса вы сможете определить, хотите ли вы разветкить свой код.
Реальное кросс-браузерное решение для потомков:
function isCrossOriginFrame() {
try {
return (!window.top.location.hostname);
} catch (e) {
return true;
}
}
console.log(isCrossOriginFrame());
Протестировано на достойном уровне рабочего стола и мобильных браузеров.
используйте заголовок x-frame, это предотвратит загрузку вашего сайта в frame/iframe. существуют различные варианты здесь читать
Если я вижу ваш прецедент:
Я бы посмотрел его на стороне сервера (кто назвал ваш сайт), используя $_SERVER['REMOTE_ADDR']
, и если это ваш IP-адрес, вы можете скрыть брендинг и ссылки.
Если прецедент предотвратит создание вашего сайта, вы можете использовать X-Frame-Options: deny
.
Другое предположение:
Элементы внутри документа имеют свойство ownerDocument
, возможно, это может помочь определить, что вы хотите.
В соответствии с вашими текущими ограничениями нет возможности достичь этого с помощью 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>
Я попытался использовать референт для определения кросс-домена, но обнаружил, что он ненадежен на многих сайтах. Может быть, кто-то найдет это полезным.
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;
}