Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/421.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 如何识别网页是在iframe中加载还是直接加载到浏览器窗口中?_Javascript_Facebook_Iframe - Fatal编程技术网

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

Javascript 如何识别网页是在iframe中加载还是直接加载到浏览器窗口中?,javascript,facebook,iframe,Javascript,Facebook,Iframe,我正在写一个基于iframe的facebook应用程序。现在,我想使用相同的html页面来呈现普通网站以及facebook中的画布页面。我想知道我是否可以确定页面是否已加载到iframe内部或直接加载到浏览器中?浏览器可能会阻止对窗口的访问。顶部由于以下原因。IE漏洞也会发生。以下是工作代码: function inIframe () { try { return window.self !== window.top; } catch (e) {

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

浏览器可能会阻止对
窗口的访问。顶部
由于以下原因。IE漏洞也会发生。以下是工作代码:

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

top
self
都是
window
对象(以及
parent
),因此您可以查看您的窗口是否是top窗口。

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

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

想象一下这个页面布局:

MainPage.html
  IframedPage1.html   (named "foo")
  IframedPage2.html   (named "bar")
    IframedPage3.html (named "baz")
现在,在“baz”帧中单击链接(无目标,在“baz”帧中加载),效果良好

如果加载的页面称为special.html,使用JS检查“it”是否有一个名为“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,因此你可以测试这个奇怪的条件。

< p>因为你在脸谱网应用程序的上下文中询问,你可能想考虑在初始请求时在服务器上检测到这个。如果从iFrAME中调用,脸谱网将通过一组查询字符串数据,包括FBSigSug用户密钥。/p>
由于您可能需要在应用程序中检查并使用此数据,因此请使用它来确定要呈现的适当上下文。

使用此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;
}
函数isNoIframeOrIframeInMyHost(){
//验证:它必须作为首页加载,或者如果它加载在iframe中
//那么它必须嵌入我自己的领域。
//信息:如果top.location.href不可访问,则它将嵌入iframe中
//不同的领域是不同的。
var myresult=true;
试一试{
var tophref=top.location.href;
var tophostname=top.location.hostname.toString();
var myhref=location.href;
如果(tophref==myhref){
myresult=true;
}else if(tophostname!=“www.yourdomain.com”){
myresult=false;
}
}捕获(错误){
//错误是无法访问top.location.href的权限错误
//(这意味着父域iframe domain)!
myresult=false;
}
返回我的结果;
}

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

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

 (window !== window.top) : false 
 (window.self !== window.top) : true
这个输出的奇怪之处在于,无论代码是在iframe还是在顶级窗口中运行,它总是相同的

另一方面,Google Chrome似乎只在顶级窗口中执行我的内容脚本一次,因此上述操作根本不起作用

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

 console.log(window.frames.length + ':' + parent.frames.length);
如果没有iframe,它将在包含一个框架的顶级窗口中打印
0:0
,并在文档的唯一iframe中打印
0:1


这使我的扩展可以在两种浏览器中确定是否存在任何iFrame,另外,在Firefox中确定它是否在其中一个iFrame中运行。

这是一段我已经使用过几次的古老代码:

if (parent.location.href == self.location.href) {
    window.location.href = 'https://www.facebook.com/pagename?v=app_1357902468';
}
我用这个:

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

但仅当您的页面中的iframe数量与加载iframe的页面中的iframe数量不同时。在页面中不使用iframe可以100%保证此代码的结果

在每个页面中编写此javascript

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

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

如果您想知道用户是否正在从facebook页面选项卡或画布访问您的应用程序,请检查已签名的请求。如果您没有收到,则可能该用户不是在从facebook访问。 确保确认已签名的_请求字段结构和字段内容

使用php sdk,您可以获得如下签名请求:

$signed_request = $facebook->getSignedRequest();
您可以在此处阅读有关已签名请求的更多信息:

在这里:


当在与父帧位于同一原点的iframe中时,该方法返回嵌入窗口的元素(例如
iframe
对象
)。否则,如果在顶级上下文中浏览,或者父帧和子帧具有不同原点,则该方法将计算为
null

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

这是一个在所有现代浏览器中都有基本支持的窗口。

我实际上曾经检查过window.parent,它对我很有用,但最近window是一个循环对象,总是有一个父键iframe或没有iframe

如评论所示,与window.parent进行比较很困难。如果iframe与parent完全相同,则不确定这是否有效

window === window.parent;

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

var iFrameDetection = (window === window.parent) ? false : true;
最适合现在使用的传统浏览器断帧脚本 其他解决方案不适用于我。此解决方案适用于所有浏览器:

防止点击劫持的一种方法是包含一个“框架”
var iFrameDetection = (window === window.parent) ? false : true;
<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>
    <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 ( window.location !== window.parent.location ) 
{
      // The page is in an iframe   
} 
else 
{     
      // The page is not in an iframe   
}
function amiLoadedInIFrame() {
    try {
         // Introduce a new propery in window.top
         window.top.dummyAttribute = true;
         // If window.dummyAttribute is there.. then window and window.top are same intances
         return !window.dummyAttribute;
    } catch(e) {
         // Exception will be raised when the top is in different domain
         return true;
    }
}
constructor() {
    let windowLen = window.frames.length;
    let parentLen = parent.frames.length;

    if (windowLen == 0 && parentLen >= 1) {
        this.isInIframe = true
        console.log('Is in Iframe!')
    } else {
        console.log('Is in main window!')
    }
}