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



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

952   15  

15 ответов:

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

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

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

window.frameElement возвращает элемент (например,

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

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

Роборг прав, но я хотел добавить боковую заметку.

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

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

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

Теперь в кадре " baz "вы нажимаете ссылку (нет цели, загружается в кадре" baz") он отлично работает.

Если страница загружается, давайте назовем ее специальной.html, использует JS, чтобы проверить, если "это" имеет Родительский кадр с именем " bar " он вернет true (ожидаемый).

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

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

пока все хорошо. Теперь приходит ошибка.

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

когда эта новая вкладка загружается (без родительских кадров вообще!)IE войдет в бесконечный цикл загрузки страницы! потому что IE "копирует" структуру фрейма в JavaScript таким образом, что новая вкладка имеет родителя, и этот родитель имеет имя "bar".

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

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

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

принятый ответ не работал для меня внутри сценария содержимого расширения Firefox 6.0 (Addon-SDK 1.0): Firefox выполняет сценарий содержимого в каждом: окне верхнего уровня и во всех iframes.

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

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

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

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

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

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

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

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

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

var isIframe = (self.frameElement && (self.frameElement+"").indexOf("HTMLIFrameElement") > -1);

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

var iFrameDetection = (window === window.parent) ? false : true;

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

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

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

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

лучший на данный момент унаследованный браузер Frame Breaking Script

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

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

в элементе головки документа добавьте следующее:

<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

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

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

window === window.parent;

Если вы хотите знать, если пользователь получает доступ к вашему приложению с вкладки страницы 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/

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

    <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>

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

if (parent.location.href == self.location.href) {
    window.location.href = 'https://www.facebook.com/pagename?v=app_1357902468';
}
if (window.frames.length != parent.frames.length) { page loaded in iframe }

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

напишите этот javascript на каждой странице

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

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

Comments

    Ничего не найдено.