Как определить, если веб-страница загружается внутри фрейма или непосредственно в окне браузера?

голоса
450

Я пишу facebook приложения IFrame основы. Теперь я хочу, чтобы использовать ту же HTML-страницу, чтобы сделать нормальный сайт, а также страницу холста внутри Facebook. Я хочу знать, могу ли я определить, была ли загружена страница внутри фрейма или непосредственно в браузере?

Задан 28/11/2008 в 16:45
источник пользователем
На других языках...                            


15 ответов

голоса
840

Браузеры могут блокировать доступ к window.topиз - за те же политику происхождения . IE ошибка также имеет место. Вот рабочий код:

function inIframe () {
    try {
        return window.self !== window.top;
    } catch (e) {
        return true;
    }
}

topи selfоба windowобъекта (вместе с parent), так что вы видите , если окно верхнего окно.

Ответил 28/11/2008 в 16:47
источник пользователем

голоса
25

RoBorg правильно, но я хотел бы добавить боковую записку.

В IE7 / IE8, когда Microsoft добавила вкладки в браузере они сломали одну вещь, которая вызовет хаос с JS, если вы не будете осторожны.

Представьте себе, это макет страницы:

MainPage.html
  IframedPage1.html   (named "foo")
  IframedPage2.html   (named "bar")
    IframedPage3.html (named "baz")

Теперь в рамке «БАЗ» щелкнуть ссылку (без цели, грузы в «БАЗ» кадр) он работает отлично.

Если страница, которая загружается, позволяет называть его special.html, использует JS, чтобы проверить, если «оно» есть родительский фрейм с именем «бар» он возвращает истину (ожидается).

Теперь давайте говорить о том, что special.html страница, когда он загружает, проверяет родительский фрейм (для существования и его имя, и если это «бар» он перегружает себя в баре кадра. Например

if(window.parent && window.parent.name == 'bar'){
  window.parent.location = self.location;
}

Все идет нормально. Теперь приходит ошибка.

Допустим, вместо того, чтобы нажать на ссылку, как оригинальный нормальный, и загрузка страницы special.html в «БАЗ» кадр, вы среднего щелкнул или выбрать, чтобы открыть его в новой вкладке.

При том , что новая вкладках нагрузка ( без каких - либо родительских кадров на всех! ) IE войдет в бесконечный цикл загрузки страницы! потому что IE «копирует» структуру кадра в JavaScript таким образом, чтобы новая вкладка Есть ли у родителя, а родитель имеет название «бар».

Хорошая новость, что проверка:

if(self == top){
  //this returns true!
}

в этой новой вкладке действительно возвращает истину, и, таким образом, вы можете проверить для этого странного состояния.

Ответил 28/11/2008 в 18:53
источник пользователем

голоса
1

Так как вы спрашиваете в контексте приложения facebook, вы можете рассмотреть возможность обнаружения этого на сервере, когда первоначальный запрос был сделан. Facebook будет проходить по связке строк запроса данных, включая ключ fb_sig_user, если она вызывается из фрейма.

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

Ответил 11/12/2008 в 23:04
источник пользователем

голоса
2

Используйте эту функцию яваскрипта в качестве примера о том, как достичь этого.

function isNoIframeOrIframeInMyHost() {
// Validation: it must be loaded as the top page, or if it is loaded in an iframe 
// then it must be embedded in my own domain.
// Info: IF top.location.href is not accessible THEN it is embedded in an iframe 
// and the domains are different.
var myresult = true;
try {
    var tophref = top.location.href;
    var tophostname = top.location.hostname.toString();
    var myhref = location.href;
    if (tophref === myhref) {
        myresult = true;
    } else if (tophostname !== "www.yourdomain.com") {
        myresult = false;
    }
} catch (error) { 
  // error is a permission error that top.location.href is not accessible 
  // (which means parent domain <> iframe domain)!
    myresult = false;
}
return myresult;
}
Ответил 21/09/2011 в 03:32
источник пользователем

голоса
16

Принятый ответ не работает для меня в скрипте содержания Firefox 6.0 Extension (Аддон-SDK 1.0): Firefox выполняет скрипт контента в каждом: окне верхнего уровня и во всех фреймах.

Внутри скрипта содержания я получаю следующие результаты:

 (window !== window.top) : false 
 (window.self !== window.top) : true

Странная вещь об этом выходе, что это всегда одинаково, независимо будет ли код работать внутри фрейма или окна верхнего уровня.

С другой стороны, Google Chrome, кажется, выполнить мое содержание скрипт только один раз в окне верхнего уровня, так что выше не будет работать вообще.

Что, наконец, работал для меня в сценарии контента в обоих браузерах это:

 console.log(window.frames.length + ':' + parent.frames.length);

Без фреймов это печатает 0:0, в окне верхнего уровня , содержащее один кадр он печатает 1:1, и в единственном IFRAME документа он печатает 0:1.

Это позволяет мое расширение, чтобы определить, в обоих браузерах, если есть какие-либо плавающие фреймы присутствуют, и, кроме того, в Firefox, если она выполняется в одном из фреймов.

Ответил 14/10/2011 в 15:32
источник пользователем

голоса
-1

Это древний кусок кода, который я использовал несколько раз:

if (parent.location.href == self.location.href) {
    window.location.href = 'https://www.facebook.com/pagename?v=app_1357902468';
}
Ответил 25/10/2011 в 04:57
источник пользователем

голоса
5

Я использую это:

var isIframe = (self.frameElement && (self.frameElement+"").indexOf("HTMLIFrameElement") > -1);
Ответил 20/06/2012 в 11:04
источник пользователем

голоса
-3
if (window.frames.length != parent.frames.length) { page loaded in iframe }

Но только если количество фреймов отличается вашей страницы и страницы, которые загружаются вам в IFRAME. Не делайте IFRAME на странице, чтобы иметь 100% гарантию результата этого кода

Ответил 27/10/2012 в 16:31
источник пользователем

голоса
-4

Написать эту JavaScript на каждой странице

if (self == top)
  { window.location = "Home.aspx"; }

Тогда он будет автоматически перенаправляет на главную страницу.

Ответил 08/02/2013 в 07:15
источник пользователем

голоса
0

Если вы хотите знать, если пользователь получает доступ приложения на вкладке facebook страницы или чек холста для Подписанного запроса. Если вы не получите его, вероятно, пользователь не имеет доступа от Facebook. Для того, чтобы убедиться, что ПОДТВЕРЖДАЕТ signed_request полой структуры и полое содержимое.

С PHP-SDK вы можете получить Подписанный запрос, как это:

$signed_request = $facebook->getSignedRequest();

Вы можете прочитать больше о Подписанный запрос здесь:

https://developers.facebook.com/docs/reference/php/facebook-getSignedRequest/

и здесь:

https://developers.facebook.com/docs/reference/login/signed-request/

Ответил 17/06/2013 в 19:08
источник пользователем

голоса
64

window.frameElementВозвращает элемент (например, <IFRAME> или <объект>), в котором окно встроено, или нуль, если окно верхнего уровня. Таким образом, идентификационный код выглядит

if (window.frameElement) {
  // in frame
}
else {
  // not in frame
}

Это стандартный и довольно новый метод. Это точно работает в Chrome и Firefox. Я не могу рекомендовать его в качестве универсального решения , но следует отметить здесь , я думаю.

Ответил 07/09/2013 в 23:55
источник пользователем

голоса
1

Я на самом деле используется для проверки window.parent и он работал на меня, но в последнее время окно представляет собой циклический объект и всегда имеет родительский ключ, встроенный или нет IFRAME.

Как замечания предлагают трудно сравнивать с window.parent работ. Не уверен, если это будет работать, если IFrame точно такой же веб-страницу в качестве родителя.

window === window.parent;
Ответил 04/03/2014 в 04:47
источник пользователем

голоса
3

Я не знаю, как этот пример работает для старых браузеров, но я использую это для IE, Firefox и Chrome без и выдач:

var iFrameDetection = (window === window.parent) ? false : true;
Ответил 19/11/2015 в 09:30
источник пользователем

голоса
0

Лучшее для, теперь устаревших браузеров кадров Ломая Script

Другие решения не работали для меня. Это один работает на всех браузерах:

Один из способов защиты от ClickJacking будет включать «каркасно-прерыватель» сценарий на каждой странице, которая не должно быть обрамлением. Следующая методика позволит предотвратить веб-страницу из подставила даже в устаревших браузерах, которые не поддерживают X-Frame-Options-заголовок.

В элементе документа HEAD, добавьте следующее:

<style id="antiClickjack">body{display:none !important;}</style>

Сначала нанесите идентификатор для самого стиля элемента:

<script type="text/javascript">
   if (self === top) {
       var antiClickjack = document.getElementById("antiClickjack");
       antiClickjack.parentNode.removeChild(antiClickjack);
   } else {
       top.location = self.location;
   }
</script>

Таким образом, все может быть в документе ГОЛОВЫ и вам нужно только один метод / TagLib в вашем API.

Справка: https://www.codemagi.com/blog/post/194

Ответил 12/04/2018 в 09:24
источник пользователем

голоса
0

Это закончило быть самым простым решением для меня.

    <p id="demofsdfsdfs"></p>

<script>

if(window.self !== window.top) {

//run this code if in an iframe
document.getElementById("demofsdfsdfs").innerHTML = "in frame";

}else{

//run code if not in an iframe
document.getElementById("demofsdfsdfs").innerHTML = "no frame";
}

</script>
Ответил 25/07/2018 в 01:15
источник пользователем

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more