当 iframe 在不同的域 iframe 中时获取相同域 iframe 的高度?
Get the height of a same domain iframe when that iframe is inside a different domain iframe?
我的网站在 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 解决方案。
不适用于我的解决方案的选项是:
- 使用 document.domain 将站点列入白名单。
- 修改 web.config 以将站点列入白名单。
就像《盗梦空间》一样,我必须更深入。请帮忙。
您将需要使用 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 库来处理您需要的通信。我知道这个研究有多痛苦,我以前做过的几天都在寻找答案。
您的代码 运行 来自 parent 和 child window 中间的 iframe。所以,任何时候你打电话给
window.parent
并且您的站点嵌入在 iframe 中并且 parent 是不同的域(同源策略),将引发错误。我建议首先检查 parent 是否同源。您需要将此检查包装在 try catch 中。
注意:如果 parent 是 http://localhost:xxx and the iframe is 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();
我的网站在 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 解决方案。
不适用于我的解决方案的选项是:
- 使用 document.domain 将站点列入白名单。
- 修改 web.config 以将站点列入白名单。
就像《盗梦空间》一样,我必须更深入。请帮忙。
您将需要使用 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 库来处理您需要的通信。我知道这个研究有多痛苦,我以前做过的几天都在寻找答案。
您的代码 运行 来自 parent 和 child window 中间的 iframe。所以,任何时候你打电话给
window.parent
并且您的站点嵌入在 iframe 中并且 parent 是不同的域(同源策略),将引发错误。我建议首先检查 parent 是否同源。您需要将此检查包装在 try catch 中。
注意:如果 parent 是 http://localhost:xxx and the iframe is 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();