Я пишу фрейм-приложение на основе iframe. Теперь я хочу использовать одну и ту же страницу html для рендеринга обычного веб-сайта, а также страницы холста в facebook. Я хочу знать, могу ли я определить, была ли загружена страница внутри iframe или непосредственно в браузере?
Как определить, загружается ли веб-страница внутри iframe или непосредственно в окне браузера?
Ответ 1
Браузеры могут блокировать доступ к window.top из-за той же политики происхождения. Ошибки IE также имеют место. Здесь рабочий код:
function inIframe () {
    try {
        return window.self !== window.top;
    } catch (e) {
        return true;
    }
}
 top и self являются объектами window (вместе с parent), поэтому вы видите, что ваше окно является верхним окном.
Ответ 2
 Когда в iframe тот же источник, что и у родителя, метод  window.frameElement возвращает элемент (например, iframe или object), в который встроено окно. В противном случае, если просмотр выполняется в контексте верхнего уровня или если родительский и дочерний фреймы имеют разное происхождение, он будет иметь null.
window.frameElement
  ? 'embedded in iframe or object'
  : 'not embedded or cross-origin'
Это стандарт HTML с базовой поддержкой во всех современных браузерах.
Ответ 3
RoBorg правильно, но я хотел добавить примечание.
В IE7/IE8, когда Microsoft добавила вкладки в свой браузер, они сломали одну вещь, которая приведет к хаосу с вашим JS, если вы не будете осторожны.
Представьте себе этот макет страницы:
MainPage.html
  IframedPage1.html   (named "foo")
  IframedPage2.html   (named "bar")
    IframedPage3.html (named "baz")
Теперь в рамке "baz" вы нажимаете ссылку (нет цели, загружается в рамке "baz" ), она отлично работает.
Если загружаемая страница позволяет вызвать ее special.html, она использует JS для проверки того, имеет ли родительский фрейм с именем "bar", он вернет true (ожидается).
Теперь скажем, что на странице special.html при загрузке проверяется родительский фрейм (для существования и его имени, а если это "бар", он перезагружается в рамке рамки, например.
if(window.parent && window.parent.name == 'bar'){
  window.parent.location = self.location;
}
Пока все хорошо. Теперь появляется ошибка.
Предположим, вместо того, чтобы нажимать на исходную ссылку, как обычно, и загружать страницу special.html в рамке "baz" , вы щелкнули ее по середине или решили открыть ее в новой вкладке.
Когда эта новая вкладка загружается ( без родительских кадров вообще! ) IE войдет в бесконечный цикл загрузки страницы!, потому что IE "копирует" структуру кадра в JavaScript, так что новая вкладка имеет родительский элемент, а у этого родителя имя "бар".
Хорошей новостью является проверка:
if(self == top){
  //this returns true!
}
в этой новой вкладке вернет true, и вы можете проверить это нечетное условие.
Ответ 4
Принятый ответ не работал у меня внутри содержимого script расширения Firefox 6.0 (Addon-SDK 1.0): Firefox выполняет содержимое script в каждом: окно верхнего уровня и во всех iframe.
Внутри содержимого script получаю следующие результаты:
 (window !== window.top) : false 
 (window.self !== window.top) : true
Странная вещь в этом выходе заключается в том, что она всегда одинакова независимо от того, выполняется ли код внутри iframe или окна верхнего уровня.
С другой стороны, Google Chrome, кажется, выполняет мой контент script только один раз в окне верхнего уровня, поэтому выше не будет работать.
Что в конечном итоге работало для меня в контенте script в обоих браузерах:
 console.log(window.frames.length + ':' + parent.frames.length);
Без iframe это печатает 0:0, в окне верхнего уровня, содержащем один кадр, он печатает 1:1, а в единственном iframe документа он печатает 0:1.
Это позволяет моему расширению определять в обоих браузерах, если есть какие-либо iframes, а также в Firefox, если он запускается внутри одного из фреймов.
Ответ 5
Я не уверен, как этот пример работает для старых веб-браузеров, но я использую это для IE, Firefox и Chrome без проблем:
var iFrameDetection = (window === window.parent) ? false : true;
Ответ 6
Я использую это:
var isIframe = (self.frameElement && (self.frameElement+"").indexOf("HTMLIFrameElement") > -1);
Ответ 7
Используйте эту функцию 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;
}
Ответ 8
Поскольку вы спрашиваете в контексте приложения facebook, вы можете захотеть обнаружить это на сервере при первоначальном запросе. Facebook будет передавать кучу данных запроса, включая ключ fb_sig_user, если он вызывается из iframe.
Так как вам, вероятно, нужно все равно проверять и использовать эти данные в своем приложении, используйте его, чтобы определить соответствующий контекст для рендеринга.
Ответ 9
Я на самом деле проверял window.parent, и он работал для меня, но в последнее время window является циклическим объектом и всегда имеет родительский ключ, iframe или нет iframe.
Поскольку комментарии предлагают трудно сравнивать с работами window.parent. Не уверен, будет ли это работать, если iframe точно такая же веб-страница, как родительский.
window === window.parent;
Ответ 10
Лучший на данный момент устаревший скрипт разрыва фрейма браузера
Другие решения не помогли мне. Этот работает во всех браузерах:
Один из способов защиты от кликджекинга состоит в том, чтобы на каждой странице был добавлен сценарий "разрыва фрейма", который не следует создавать в рамке. Следующая методология предотвратит создание веб-страницы даже в старых браузерах, которые не поддерживают X-Frame-Options-Header.
В элемент документа 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>
Таким образом, все может быть в документе HEAD, и вам нужен только один метод /taglib в вашем API.
Ответ 11
Это оказалось самым простым решением для меня.
    <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>
Ответ 12
Это древний фрагмент кода, который я использовал несколько раз:
if (parent.location.href == self.location.href) {
    window.location.href = 'https://www.facebook.com/pagename?v=app_1357902468';
}
Ответ 13
Если вы хотите узнать, обращается ли пользователь к вашему приложению со страницы вкладки 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/
Ответ 14
if (window.frames.length != parent.frames.length) { page loaded in iframe }
Но только если число ваших iframe отличается на вашей странице и странице, которые загружают вас в iframe. Не делайте iframe на своей странице, чтобы получить 100% гарантию результата этого кода.
Ответ 15
Напишите этот javascript на каждой странице
if (self == top)
  { window.location = "Home.aspx"; }
Затем он автоматически перенаправляется на домашнюю страницу.
