【问题标题】:Get the height of a same domain iframe when that iframe is inside a different domain iframe?当 iframe 在不同的域 iframe 中时,获取相同域 iframe 的高度?
【发布时间】:2017-10-20 02:04:19
【问题描述】:

我有一个网站,它在 iframe 中嵌入了媒体播放器。媒体播放器和站点在同一个域中,防止跨域问题。每个页面,主页面以及媒体播放器页面,都有一些代码可以找到任何父 iframe 的高度和宽度:

var height = $(parent.window).height();
var width = $(parent.window).width();

到目前为止没有问题......直到:

一位客户希望将我的网站嵌入到他自己网站的 iframe 中。他的网站位于不同的域中。现在,我的 iframe 在另一个 iframe 中,我的代码抛出了跨域错误。

以下不会抛出错误:

var test1 = parent.window; // returns my site
var test2 = window.top;  // returns client site

以下确实会引发跨域错误:

var test3 = parent.window.document;
var test4 = $(parent.window);
var test5 = window.top.document;
var test6 = $(window.top);

如何在不出现跨域错误的情况下获取域中 iframe 的高度?我希望有一个纯 javascript/jQuery 解决方案。

不适用于我的解决方案的选项是:

  1. 使用 document.domain 将站点列入白名单。
  2. 修改 web.config 以将该站点列入白名单。

就像在《盗梦空间》中一样,我必须更深入。请帮忙。

【问题讨论】:

    标签: javascript jquery iframe cross-domain same-origin-policy


    【解决方案1】:

    您需要使用Javascript's messager。首先,你需要像这样定义一个function

    function myReceiver(event) {
        //Do something
    }
    

    那么你需要一个事件监听器:

    window.addEventListener("message", myReceiver);
    

    两边都需要这样的东西。现在,您可以向iframe 发送这样的消息:

    innerWindow.contentWindow.postMessage({ message: {ResponseKey: "your response key", info1: "something1", info2: "something2"}}, innerWindow.src)
    

    这就是您可以向父母发送消息的方式:

    window.parent.postMessage({ message: {ResponseKey: "your response key", info1: "something1", info2: "something2"}}, myorigin);
    

    谜题中唯一缺少的项目是myorigin。您可以在消息接收者事件中使用event.origin || event.originalEvent.origin 在您的iframe 中找到它。

    但是,在 iframe 内的页面中使用您网站的页面必须包含一个 Javascript 库,该库将处理您所需的通信。我知道这项研究有多痛苦,我已经花了好几天的时间才找到答案。

    【讨论】:

    • 我喜欢使用它来反转控制的想法。当我的父页面有页面 resize() 事件时,它可以向子 iframe 页面发送新尺寸的消息。
    【解决方案2】:

    您的代码从父窗口和子窗口中间的 iframe 运行。所以,只要你打电话

    window.parent
    

    如果您的网站嵌入在 iframe 中,并且父级是不同的域(同源策略),则会引发错误。我建议首先检查父母是否是同一来源。您需要将此检查包装在 try catch 中。

    注意:如果父级是 http://localhost:xxx 并且 iframe 是 http://localhost:zzz 其中 xxx 是与 zzz 不同的端口号,大多数浏览器,但不是 Edge,不会抛出错误。因此,您还需要通过比较协议、域和端口来手动检查源匹配。

    var isEmbeddedInCrossOriginIframe = false;
    try {
      var originSelf = (window.self.location.protocol + '//' + 
                        window.self.location.hostname + 
                       (window.self.location.port ? ':' + 
                        window.self.location.port : '')).toLowerCase();
      var originParentOrSelf = (window.parent.location.protocol + '//' + 
                        window.parent.location.hostname + 
                       (window.parent.location.port ? ':' + 
                        window.parent.location.port : '')).toLowerCase();
      isEmbeddedInCrossOriginIframe = originSelf != originParentOrSelf;
    }
    catch(err) {
      isEmbeddedInCrossOriginIframe = true;
      //console.log(err);
    }
    

    您的解决方案将是:

    var height = $(isEmbeddedInCrossOriginIframe ? window : parent.window)
                 .height();
    var width = $(isEmbeddedInCrossOriginIframe ? window : parent.window)
                .width();
    

    【讨论】:

      猜你喜欢
      • 2016-10-11
      • 2012-12-16
      • 1970-01-01
      • 1970-01-01
      • 2012-01-24
      • 2022-01-17
      • 2011-09-28
      • 1970-01-01
      相关资源
      最近更新 更多