从iframe访问父窗口(跨域)

13

我遇到了一个任务,需要从iFrame访问父窗口,但如果iFrame中的窗口是从另一个域加载的,则所有现代浏览器都不允许这样做。因此,我在这里寻找最佳解决方案。

我将通过以下方式完成此任务:

我有一个带有iFrame的覆盖层。这将替代弹出窗口,以防止弹出窗口拦截器阻止我的内容。任务是在iFrame中的文档完成某些工作时重新加载主页面。 在将加载到iFrame的文档中,我将添加

<div id="is_closed" class="false"></div>

在父窗口中,我将添加一个函数,每秒钟调用一次该函数并检查此div是否仍具有classname "false"。 当这被更改为"true"时,我将调用一些回调函数。

如果您有任何更好的解决方案,请与我分享。 感激任何帮助。

编辑:这是不可能的,因为不仅无法从子窗口操作父窗口,反之亦然。 我的想法是从父窗口操作子窗口。 我错了。


2
如果我理解正确的话,现代浏览器都允许这样做。所以我在这里寻找最佳解决方案。这就是你的解决方案。你所问的是不可能实现的。 - James Hill
11
postMessage 可以在不同域名的 iframe 之间使用,并实现数据传输。 - kirilloid
2
Malgin:如果这是可能的话,任何Iframe内容都可以劫持托管页面。这已经被故意禁用了。没有解决方法也不会有“最佳解决方案”。 - Diodeus - James MacFarlane
5个回答

42

1
这是正确的答案。在HTML5中,使用Window.postMessage现在可以实现窗口(或iframe)之间的跨域js调用。 - Molomby
除了在IE < EDGE中,在跨域的Windows/Frame中使用。 - frandroid
1
是的,window.postmessage 是正确的方法... 但是,你并不总是能够访问子 iframe 的代码!因此,如果你将你的答案与我的结合起来,你就有了一个完全可行的解决方案! - 255.tar.xz

16
如果我理解正确,所有现代浏览器都允许这样做。所以我在这里寻找最佳解决方案。
这是您的解决方案。你所要求的是不可能的。
请参考相关问题: 编辑 如下评论所述,@JeremysAwesome's answer提供了一种在特定情况下允许跨域请求的方法。有关更多信息,请参见下面的SO问题。

绕过同源策略的方法


1
我知道从子窗口操作父窗口是不可能的。我想要的是如何模拟这种操作。换句话说,子窗口上的某个标志将触发父窗口运行一些代码。 - Vitaliy Lebedev
1
@Malgin,这是不可能的。您正在要求页面之间进行脚本级交互。这是不可能的。您无法模仿无法完成的事情。有很多关于此的SO问题。请参见编辑。 - James Hill
1
你的回答中唯一让我不太清楚的是,无法从父窗口操作子窗口。这正是我的想法,让我更加坚持。再次感谢。 - Vitaliy Lebedev
你可以改变窗口位置。如果你知道相关的URL并且控制着两个域名,你可能可以使用查询字符串在两者之间发送消息。不过听起来你应该追求一个更好的解决方案。 - TheXenocide
4
正如其他人所指出的那样,这确实是可能的,例如通过 postMessage。因此,@jeremysawesome 的答案应该被接受。 - Don Ho
如果您控制父元素和子元素,那么这是可能的。但是,如果您只能访问子元素呢? - lmblanes

7

但是您可以更改iframesrc属性(例如添加一个#hashtag),并在子窗口中侦听onhashchange事件。考虑到您可以更改两个页面。


我的答案让你在不控制两个页面的情况下完成这个操作! - 255.tar.xz

0

另外一种方法是:在 IFrame 加载后约 500 毫秒将其 src 设置为 javascript: 链接。示例:

setTimeout(function() {
  document.getElementsByTagName("iframe")[0].src = `javascript: 
      (function(){
          setInterval(function() {
          if (document.getElementById("is_closed").className.match(/true/g)) {
              ...//see @jeremysawesome on how to do window.postMessage
          }
      })()`
}, 500);

虽然 @jeremysawesome 的回答可行,但这将在嵌入式 iframe 上工作,无论主机域是什么,这对于在托管在像 blogspot.com 这样的域上的网站上工作时非常有用,因为你无法轻松更改此类型的内容...
现在显然仍然需要启动 window.postMessage,在 @jeremysawesome's answer 中可以找到更多信息。

-5

在sessionStorage中设置一个变量/项,并根据需要在两侧使用。 localStorage可以长时间使用。

安全风险是有人使用和操纵它来劫持你的网站。但是,如果有人想这样做,总会有可能。

记住:生命总会找到出路... ;-)


1
问题是跨域访问。你不能跨域访问本地存储/会话存储吗? - Sudi
如果您知道变量的名称,您可以跨域使用它。 - Gerd Dirk Zweäns

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接