Я пишу facebook приложения IFrame основы. Теперь я хочу, чтобы использовать ту же HTML-страницу, чтобы сделать нормальный сайт, а также страницу холста внутри Facebook. Я хочу знать, могу ли я определить, была ли загружена страница внутри фрейма или непосредственно в браузере?
Как определить, если веб-страница загружается внутри фрейма или непосредственно в окне браузера?
Браузеры могут блокировать доступ к window.topиз - за те же политику происхождения . IE ошибка также имеет место. Вот рабочий код:
function inIframe () {
try {
return window.self !== window.top;
} catch (e) {
return true;
}
}
topи selfоба windowобъекта (вместе с parent), так что вы видите , если окно верхнего окно.
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!
}
в этой новой вкладке действительно возвращает истину, и, таким образом, вы можете проверить для этого странного состояния.
Так как вы спрашиваете в контексте приложения facebook, вы можете рассмотреть возможность обнаружения этого на сервере, когда первоначальный запрос был сделан. Facebook будет проходить по связке строк запроса данных, включая ключ fb_sig_user, если она вызывается из фрейма.
Так как вы, вероятно, нужно проверить и использовать эти данные в любом случае в вашем приложении, используйте его, чтобы определить соответствующий контекст для визуализации.
Используйте эту функцию яваскрипта в качестве примера о том, как достичь этого.
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;
}
Принятый ответ не работает для меня в скрипте содержания 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, если она выполняется в одном из фреймов.
Это древний кусок кода, который я использовал несколько раз:
if (parent.location.href == self.location.href) {
window.location.href = 'https://www.facebook.com/pagename?v=app_1357902468';
}
Я использую это:
var isIframe = (self.frameElement && (self.frameElement+"").indexOf("HTMLIFrameElement") > -1);
if (window.frames.length != parent.frames.length) { page loaded in iframe }
Но только если количество фреймов отличается вашей страницы и страницы, которые загружаются вам в IFRAME. Не делайте IFRAME на странице, чтобы иметь 100% гарантию результата этого кода
Написать эту JavaScript на каждой странице
if (self == top)
{ window.location = "Home.aspx"; }
Тогда он будет автоматически перенаправляет на главную страницу.
Если вы хотите знать, если пользователь получает доступ приложения на вкладке 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/
window.frameElementВозвращает элемент (например, <IFRAME> или <объект>), в котором окно встроено, или нуль, если окно верхнего уровня. Таким образом, идентификационный код выглядит
if (window.frameElement) {
// in frame
}
else {
// not in frame
}
Это стандартный и довольно новый метод. Это точно работает в Chrome и Firefox. Я не могу рекомендовать его в качестве универсального решения , но следует отметить здесь , я думаю.
Я на самом деле используется для проверки window.parent и он работал на меня, но в последнее время окно представляет собой циклический объект и всегда имеет родительский ключ, встроенный или нет IFRAME.
Как замечания предлагают трудно сравнивать с window.parent работ. Не уверен, если это будет работать, если IFrame точно такой же веб-страницу в качестве родителя.
window === window.parent;
Я не знаю, как этот пример работает для старых браузеров, но я использую это для IE, Firefox и Chrome без и выдач:
var iFrameDetection = (window === window.parent) ? false : true;
Лучшее для, теперь устаревших браузеров кадров Ломая 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.
Это закончило быть самым простым решением для меня.
<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>













