我正在写一个基于iframe的facebook应用程序。现在我想使用相同的html页面来渲染正常的网站以及facebook内的画布页面。我想知道我是否可以确定页面是否已经在iframe内加载或直接在浏览器中加载?


当前回答

在每一页写这个javascript

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

然后它会自动重定向到主页。

其他回答

“机器人”是对的,但我想补充一点。

在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”,它会在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,因此您可以测试这种奇怪的条件。

浏览器会阻塞对窗口的访问。顶部由于同源政策。IE漏洞也会发生。下面是工作代码:

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

Top和self都是窗口对象(还有父窗口),所以你会看到你的窗口是否是顶部窗口。

我不确定这个例子如何适用于旧的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中运行还是在顶级窗口中运行,它总是相同的。

另一方面,谷歌Chrome似乎只在顶级窗口内执行我的内容脚本一次,所以上面不会工作。

在两种浏览器的内容脚本中,最终为我工作的是:

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

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

这允许我的扩展在两个浏览器中确定是否存在任何iframes,此外,在Firefox中,如果它是在iframes之一中运行。

当在与父元素相同的iframe中,window. frameelement方法返回嵌入窗口的元素(例如iframe或object)。否则,如果在顶级上下文中浏览,或者如果父帧和子帧有不同的起源,它将求值为null。

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

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