我正在编写一个基于 iframe 的 Facebook 应用程序。现在我想使用相同的 html 页面来呈现普通网站以及 facebook 中的画布页面。我想知道是否可以确定页面是在iframe中加载还是直接在浏览器中加载?
如何识别网页是在 iframe 中加载还是直接加载到浏览器窗口中?
window.top
由于同源策略,浏览器可以阻止访问。IE 错误也会发生。这是工作代码:
function inIframe () {
try {
return window.self !== window.top;
} catch (e) {
return true;
}
}
top
和self
都是window
对象(以及parent
),因此您会看到您的窗口是否是顶部窗口。
当在与父级位于同一原点的 iframe 中时,该window.frameElement
方法返回嵌入窗口的元素(例如iframe
或object
)。否则,如果在顶级上下文中浏览,或者如果父框架和子框架具有不同的来源,它将评估为null
。
window.frameElement
? 'embedded in iframe or object'
: 'not embedded or cross-origin'
这是一个HTML 标准,在所有现代浏览器中都有基本支持。
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,因此您可以测试这种奇怪的情况。
我不确定这个示例如何适用于较旧的 Web 浏览器,但我将它用于 IE、Firefox 和 Chrome,没有任何问题:
var iFrameDetection = (window === window.parent) ? false : true;
在 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 中运行。