当iframe位于不同的域iframe中时,获取同一域iframe的高度?

时间:2017-05-19 20:31:21

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

我有一个网站,其中嵌入了iframe中的媒体播放器。媒体播放器和网站位于同一个域中,可防止出现跨域问题。每个页面,主页面和媒体播放器页面都有一些代码,可以找到任何父i​​frame的高度和宽度:

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修改为白名单。
  3. 就像Inception一样,我必须更深入。请帮忙。

2 个答案:

答案 0 :(得分: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。您可以在消息接收器事件中使用iframeevent.origin || event.originalEvent.origin中找到它。

但是,在iframe内的网页中使用您网站的网页必须包含一个Javascript库,用于处理您需要的通信。我知道这项研究有多痛苦,我花了几天时间才完成这项研究,找出答案。

答案 1 :(得分:0)

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

window.parent

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

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

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();