如何识别网页是在 iframe 中加载还是直接加载到浏览器窗口中?

IT技术 javascript facebook iframe
2021-01-10 10:32:16

我正在编写一个基于 iframe 的 Facebook 应用程序。现在我想使用相同的 html 页面来呈现普通网站以及 facebook 中的画布页面。我想知道是否可以确定页面是在iframe中加载还是直接在浏览器中加载?

6个回答

window.top由于同源策略,浏览器可以阻止访问IE 错误也会发生。这是工作代码:

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

topself都是window对象(以及parent),因此您会看到您的窗口是否是顶部窗口。

这在 Firefox 中似乎运行良好。它是否也适用于其他浏览器?
2021-03-14 10:32:16
在 iframe 中有一个带有 iframe 的页面,为了从我的子 iframe 测试我的父 iframe 是否嵌入到页面中,我使用了 if (parent === top)
2021-03-20 10:32:16
@sglessard 如果子页面和父页面来自不同的域,那么 Firefox 会抱怨同源策略 (www.w3.org/Security/wiki/Same_Origin_Policy) 并且代码将不起作用
2021-03-22 10:32:16
对于那些仍在使用 1995 年最新技术的人来说,当从,或 的内容中运行时window.self !== window.top返回trueframe iframe
2021-03-26 10:32:16
这对我来说适用于 IE 11、10 和 9。它也适用于 FF 和 Opera,当然也适用于 Chrome。我没有遇到任何问题。
2021-03-28 10:32:16

当在与父级位于同一原点的 iframe 中时,该window.frameElement方法返回嵌入窗口的元素(例如iframeobject)。否则,如果在顶级上下文中浏览,或者如果父框架和子框架具有不同的来源,它将评估为null

window.frameElement
  ? 'embedded in iframe or object'
  : 'not embedded or cross-origin'

这是一个HTML 标准,在所有现代浏览器中都有基本支持。

只是为了澄清回报应该是什么: 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.
2021-03-22 10:32:16
像魅力一样工作,包括在同域嵌套 iframe 上。非常感谢!
2021-03-23 10:32:16
得到null的内部和外部iframe
2021-03-28 10:32:16
请注意frameElement,根据W3C 的说法,尝试读取将在跨域 iframe 中引发 SecurityError 异常WHATWG表示它应该返回 null)。所以你可能想把它包装在一个try...catch语句中。
2021-04-02 10:32:16
MDN 上的描述说“如果嵌入它的文档具有不同的来源(例如来自不同的域),则这是 null。”
2021-04-07 10:32:16

RoBorg 是正确的,但我想添加一个旁注。

在 IE7/IE8 中,当微软在他们的浏览器中添加标签时,他们破坏了一件如果你不小心就会对你的 JS 造成严重破坏的事情。

想象一下这个页面布局:

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

现在在“baz”框架中单击一个链接(没有目标,加载到“baz”框架中)它工作正常。

如果页面被加载,我们称之为 special.html,使用 JS 来检查“它”是否有一个名为“bar”的父框架,它将返回 true(预期)。

现在让我们说 special.html 页面在加载时检查父框架(是否存在及其名称,如果它是“bar”,它会在条形框架中重新加载自己。例如

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

到现在为止还挺好。现在来了错误。

假设不是像往常一样点击原始链接,并在“baz”框架中加载 special.html 页面,而是用中键单击它或选择在新选项卡中打开它。

当新标签加载时(根本没有父框架!IE 将进入页面加载的无限循环!因为 IE 在 JavaScript 中“复制”了框架结构,因此新选项卡确实有一个父级,并且该父级的名称为“bar”。

好消息是,检查:

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

在那个新选项卡中确实返回 true,因此您可以测试这种奇怪的情况。

在此期间该错误是否已修复?我无法在 IE8 中重现它。我总是得到正确的window.parent
2021-03-18 10:32:16
现在是 2021 年,我还在 IE 的坟墓上跳舞。
2021-03-21 10:32:16
可悲的是,我仍然支持 IE...虽然我肯定会庆祝我不再需要的那一天。;-)
2021-03-21 10:32:16
不确定 - 我将再次针对 IE9 及以下版本运行我的测试套件并发布更新。
2021-04-01 10:32:16

我不确定这个示例如何适用于较旧的 Web 浏览器,但我将它用于 IE、Firefox 和 Chrome,没有任何问题:

var iFrameDetection = (window === window.parent) ? false : true;
窗口 !== window.parent
2021-03-11 10:32:16
或者干脆 !(window===window.parent)
2021-03-16 10:32:16
伊万的建议如何使用!==
2021-03-21 10:32:16
@CalculatorFeline 我更喜欢作者写的明确声明,因为乍一看可以更快理解,因此代码错误更少。Minificator 工具为我完成这项工作,以便在部署时以最短的方式重写它。为什么我应该编写对人类来说可读性更差的缩小代码?
2021-03-29 10:32:16
iFrameDetection在弹出窗口的情况下返回误报。所以要正确检测 iframe 应该是var iFrameDetection = (window === window.parent || window.opener) ? false : true;
2021-03-30 10:32:16

在 Firefox 6.0 扩展(Addon-SDK 1.0)的内容脚本中,接受的答案对我不起作用:Firefox 在每个:顶级窗口和所有 iframe 中执行内容脚本。

在内容脚本中,我得到以下结果:

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

这个输出的奇怪之处在于,无论代码是在 iframe 还是在顶级窗口中运行,它总是相同的。

另一方面,谷歌浏览器似乎只在顶级窗口中执行一次我的内容脚本,因此上述内容根本不起作用。

最终在两种浏览器的内容脚本中对我有用的是:

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

如果没有 iframe,这会0:0在包含一个框架的顶级窗口中打印1:1,并且在文档的唯一 iframe 中打印0:1

这允许我的扩展程序在两个浏览器中确定是否存在任何 iframe,另外在 Firefox 中是否在 iframe 中运行。

尝试document.defaultView.self === document.defaultView.topwindow !== window.top在 Firefox 的附加 SDK 的内容脚本中,全局self对象是用于与主脚本通信的对象。
2021-03-26 10:32:16