Я пишу приложение Facebook на основе iframe. Теперь я хочу использовать ту же HTML-страницу для рендеринга обычного веб-сайта, а также страницу холста в Facebook. Я хочу знать, могу ли я определить, была ли страница загружена внутри iframe или непосредственно в браузере?
javascript
facebook
iframe
Akshat
источник
источник
Ответы:
Браузеры могут заблокировать доступ
window.top
из-за той же политики происхождения . IE ошибки тоже имеют место. Вот рабочий код:top
иself
обаwindow
объекта (вместе сparent
), так что вы видите, является ли ваше окно верхним окном.источник
window.self !== window.top
возвращается,true
когда запускается из содержимогоframe
, илиiframe
.Когда iframe находится в том же источнике, что и родительский
window.frameElement
элемент , метод возвращает элемент (например,iframe
orobject
), в который встроено окно. В противном случае, если просмотр выполняется в контексте верхнего уровня, или если родительский и дочерний фреймы имеют разные источники, он оценивается какnull
.Это стандарт HTML с базовой поддержкой во всех современных браузерах.
источник
frameElement
вызовет исключение SecurityError в кросс-исходных фреймах, согласно W3C ( WHATWG говорит, что вместо этого должно возвращаться ноль). Таким образом, вы можете захотеть обернуть это внутриtry...catch
утверждения.null
внутрь и наружуiframe
Returns the element (such as <iframe> or <object>) in which the window is embedded, or null if the element is either top-level or is embedded into a document with a different script origin; that is, in cross-origin situations.
Роборг прав, но я хотел добавить примечание.
В IE7 / IE8, когда Microsoft добавила вкладки в свой браузер, они нарушили одну вещь, которая вызовет хаос в вашем JS, если вы не будете осторожны.
Представьте себе этот макет страницы:
Теперь во фрейме «baz» вы нажимаете на ссылку (нет цели, загружается в фрейм «baz»), все работает нормально.
Если загружаемая страница, давайте назовем ее special.html, использует JS, чтобы проверить, есть ли у «нее» родительский фрейм с именем «bar», она вернет истину (ожидаемо).
Теперь допустим, что страница special.html при загрузке проверяет родительский фрейм (на наличие и его имя, и, если это «bar», перезагружается в фрейме bar. Например,
Все идет нормально. Теперь приходит ошибка.
Допустим, вместо того, чтобы нажимать на исходную ссылку, как обычно, и загружать страницу special.html во фрейме «baz», вы щелкаете ее по среднему щелчку или решили открыть ее в новой вкладке.
Когда эта новая вкладка загружается ( без родительских фреймов вообще! ), IE вступает в бесконечный цикл загрузки страницы! потому что IE «копирует» структуру фрейма в JavaScript, так что новая вкладка имеет родителя, и у этого родителя есть имя «bar».
Хорошей новостью является то, что проверка:
в этой новой вкладке возвращается true, и, таким образом, вы можете проверить это странное условие.
источник
window.parent
.Принятый ответ не работал для меня в скрипте контента расширения Firefox 6.0 (Addon-SDK 1.0): Firefox выполняет скрипт контента в каждом: окне верхнего уровня и во всех фреймах.
Внутри скрипта контента я получаю следующие результаты:
Странная вещь в этом выводе состоит в том, что он всегда один и тот же, независимо от того, выполняется ли код внутри iframe или окна верхнего уровня.
С другой стороны, кажется, что Google Chrome выполняет мой контент-скрипт только один раз в окне верхнего уровня, поэтому вышеописанное не будет работать вообще.
Что в итоге сработало для меня в скрипте контента в обоих браузерах:
Без iframe это печатает
0:0
, в окне верхнего уровня, содержащем один кадр, который он печатает1:1
, и в единственном iframe документа, который это печатает0:1
.Это позволяет моему расширению определять в обоих браузерах, присутствуют ли какие-либо iframe, и дополнительно в Firefox, если оно запускается внутри одного из iframe.
источник
document.defaultView.self === document.defaultView.top
илиwindow !== window.top
. В сценарии содержимого дополнительного SDK Firefox глобальныйself
объект - это объект, используемый для связи с основным сценарием.Я не уверен, как этот пример работает для старых веб-браузеров, но я использую это для IE, Firefox и Chrome без и выпускать:
источник
!(window===window.parent)
Я использую это:
источник
.indexOf("HTMLIFrameElement")
?Используйте эту функцию javascript в качестве примера того, как этого добиться.
источник
Лучший на данный момент устаревший скрипт разрыва фрейма браузера
Другие решения не работали для меня. Этот работает во всех браузерах:
Один из способов защиты от кликджекинга состоит в том, чтобы на каждой странице был добавлен сценарий «разрыва фрейма», который не следует создавать в рамке. Следующая методология предотвратит создание веб-страницы даже в устаревших браузерах, которые не поддерживают X-Frame-Options-Header.
В элемент документа HEAD добавьте следующее:
Сначала примените идентификатор к самому элементу стиля:
Таким образом, все может быть в документе HEAD, и вам нужен только один метод / taglib в вашем API.
Ссылка: https://www.codemagi.com/blog/post/194
источник
источник
Поскольку вы спрашиваете в контексте приложения Facebook, вы можете рассмотреть возможность обнаружения этого на сервере, когда сделан первоначальный запрос. Facebook будет передавать кучу данных строки запроса, включая ключ fb_sig_user, если он вызывается из iframe.
Так как вам, вероятно, все равно нужно проверить и использовать эти данные в вашем приложении, используйте их, чтобы определить соответствующий контекст для рендеринга.
источник
Я на самом деле проверял window.parent, и он работал для меня, но в последнее время window является циклическим объектом и всегда имеет родительский ключ, iframe или нет iframe.
Поскольку комментарии предлагают трудно сравнивать с работами window.parent. Не уверен, будет ли это работать, если iframe точно такая же веб-страница, как родительский.
источник
window.parent === window
это правда. Так что ваш ответ неверен. И это сравнение может быть использовано для проверки (по крайней мере, в Chrome, не проверял его в других браузерах).Это древний кусок кода, который я использовал несколько раз:
источник
(parent.location == self.location)
parent.location
. В противном случае выдается исключениеЕсли вы хотите узнать, имеет ли пользователь доступ к вашему приложению на вкладке страницы Facebook или на холсте, проверьте подписанный запрос. Если вы не получили его, вероятно, пользователь не имеет доступа с Facebook. Чтобы убедиться, подтвердите структуру полей Sign_request и содержание полей.
С помощью php-sdk вы можете получить подписанный запрос следующим образом:
Вы можете прочитать больше о подписанном запросе здесь:
https://developers.facebook.com/docs/reference/php/facebook-getSignedRequest/
и здесь:
https://developers.facebook.com/docs/reference/login/signed-request/
источник
Это оказалось самым простым решением для меня.
источник
Но только если количество фреймов отличается на вашей странице и странице, которые загружают вас в фрейм. Не делайте фрейм на своей странице, чтобы иметь 100% гарантию результата этого кода
источник
Написать этот JavaScript на каждой странице
Затем он автоматически перенаправляет на домашнюю страницу.
источник