繁体   English   中英

检测此页面是否为跨域iframe的万无一失的方法

[英]Foolproof way to detect if this page is INSIDE a cross-domain iframe

检测iframe是否为跨域 ”的“ 万无一失的方法 ”的答案描述了一种方法,用于测试页面上的iframe是指向同域还是跨域页面,解决不同浏览器对跨域策略的解释和避免会中断用户或停止javascript的错误消息。

我正在寻找相当于这个但是 iframe内部的子页面测试它是否跨域iframe 内部

可以使用 parent全局访问(相同域)有关父对象的信息,例如parent.document.location ,但有没有可靠的方法来执行此跨浏览器而不会在检测到父对象是跨域时崩溃


对于方便的测试, 这里是一个jsfiddle中jsbin ,在尝试测试parent.location.host是否可访问时崩溃成错误。 是否有一种可靠的方法来获取可用的东西,比如false告诉我们这是一个跨域父,而不是错误?

是否有一个try...catch变体将是强大的跨浏览器? 或者使用来自parent.postMessage()的返回值的一些巧妙技巧? (虽然父页面无法编辑)


使用案例:想象嵌入在自己网站上的页面上的可嵌入内容,以及第三方。 如果页面位于同域iframe上,我们会隐藏品牌并链接回原始网站,因为用户已在此处。 如果他们从第三方iframe访问该页面或直接加载页面,我们会显示品牌和信用,以便他们可以看到内容的来源。


为了澄清,我知道同一个域政策,我不关心的跨浏览器领域是什么 ,我只是希望写一个简单但可靠的if条件一样if( crossDomainParent() ){ /* do something */}

首先检查你是否是IFramed。

window.self !== window.top

如果您是IFramed,那么您的推荐人是您的父框架网址。

document.referrer

通过此URL,您应该能够检测是否要分支代码。

真正的后期浏览器解决方案:

function isCrossOriginFrame() {
  try {
    return (!window.top.location.hostname);
  } catch (e) {
    return true;
  }
}

console.log(isCrossOriginFrame());

在大量的桌面和移动浏览器上进行测试。

https://jsfiddle.net/arzd4btc/3/

使用x-frame标头,这将阻止您的网站加载到frame / iframe。 有不同的选项在这里阅读

如果我看到你的用例:

我会检查服务器端( $_SERVER['REMOTE_ADDR']你的网站),使用$_SERVER['REMOTE_ADDR'] ,如果它是你的IP,你可以隐藏品牌和链接。

如果用例即将阻止您的网站框架,您可以使用X-Frame-Options: deny

其他猜测:文档中的元素具有ownerDocument属性,也许可以帮助检测您想要的内容。

根据您当前的限制,使用DOM API无法实现此目的。 使用属于另一个域的窗口进行的任何评估都会显示错误。

但是,“hack”是从您的子窗口发送XHR以加载您域中的已知页面。 如果此XHR成功完成,则您知道两个窗口都是同一个域。

但是,这会将错误消息记录到控制台。

试试这个(在iframe中)

<script type="text/javascript">
  var detectOrigin = (window.location.ancestorOrigins === undefined ? 
  /example.com/.test(document.domain) /* firefox */ : 
  /example.com/.test(window.location.ancestorOrigins[0])); /* webkit */
  if (detectOrigin === true) {console.log(detectOrigin)}; /* `true` example.com origin */
  if (detectOrigin === false) {console.log(detectOrigin)}; /* `false` !example.com origin */
</script>

我试图使用referer来确定跨域,但我发现它在许多站点上都不可靠。 也许有人会觉得这很有用。

function IsCrossDomainFrame() {
    if( parent === window ) return false; //not a frame
    var parentLocation = new URL(document.referer);//the referer of an iframe is the parent
    return (parentLocation.protocol !== location.protocol ||
            parentLocation.hostname !== location.hostname ||
            parentLocation.port     !== location.port);
}

协议,主机名和端口确定跨域。

对于嵌套的iframe:一种递归方式来了解iframe(执行此代码的位置)是否是跨域的:

function crosDomIfrm(win, data) {
        data = (typeof data === 'undefined')?{ref:win.document.location,isCD:false}:data;
        try { 
            if( win.document.referrer != '' ){
                data.isCD = parseURL(data.ref) != parseURL(win.document.referrer);
            }
        } catch(e){}
        if ( (win.self !== win.parent) && !data.isCD ) { //I'm in iframe
            data = crosDomIfrm( win.parent, data );
        }
        return {ref:data.ref,isCD:data.isCD};
    },

function parseURL(url) {
                var a=document.createElement('a');
                a.href=url;
                return a.hostname;
            }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM