从 IFrame 更改父窗口的 URL

Posted

技术标签:

【中文标题】从 IFrame 更改父窗口的 URL【英文标题】:Changing parent window's URL from IFrame 【发布时间】:2010-12-24 01:06:45 【问题描述】:

我有一种情况,我在两台不同的服务器上有 Web 应用程序,其中 App1 在 IFrame 中包含 App2。 App2 中的任何链接都可以具有target="_parent" 属性,该属性允许这些链接在顶部窗口中打开。但是,我找不到任何方法在 javascript 中获得相同的行为。我发现this page,它声称子框架可以使用parent.foo() 在父框架上调用javascript,但这似乎在IE8 或FF3.5 中不起作用。我找到了this SO question,它解释了这个安全模型是如何工作的。但奇怪的是,我不能用 Javascript 做我可以用简单的<a> 标签做的事情。 有什么解决方法吗?我知道window.postMessage,但是(据我所知)这只适用于Firefox。


示例

server1/test.html

<html>
<head>
<script type="text/javascript">
function myCallback(foo) 
  alert(foo);

</script>
</head>
<body>
<iframe src="http://server2/test2.htm"  ></iframe>
</body></html>

server2/test2.html

<html><body>
<script>
function clickit() 
  parent.document.location = "http://www.google.com"; //not allowed
  parent.myCallback("http://www.google.com"); //not allowed

</script>
<p>This should be in an iFrame!</p>
<p><a href="http://www.google.com" target="_parent">normal link (works)</a></p>
<p><a href="javascript:clickit()">javascript link</a></p>
</body></html>

【问题讨论】:

【参考方案1】:

好的,我做了更多调查,似乎 postMessage 在所有现代浏览器中都有效,甚至 IE 也是如此(需要注意的是 IE 的处理方式略有不同)。这是我如何让它工作的(在 IE8、FF3.5、Chrome 3.0、Safari 4 beta、Opera 9.64 的 WinXP 上测试):

server1/test.html

<html>
<head>
<script type="text/javascript">
if(navigator.appName == "Microsoft Internet Explorer")
  window.attachEvent("onmessage", receiveMessage);
else
  window.addEventListener("message", receiveMessage, false);

function receiveMessage(e) 
  if(e.origin == "http://server2") //important for security
    if(e.data.indexOf('redirect:') == 0)
      document.location = e.data.substr(9);

</script>
</head>
<body>
<iframe src="http://server2/test2.htm"  ></iframe>
</body>
</html>

server2/test2.htm

<html><body>
<script>
function clickit() 
  parent.postMessage('redirect:http://www.google.com', 'http://server1');

</script>
<p>This should be in an iFrame!</p>
<p><a href="http://www.google.com" target="_parent">normal link</a></p>
<p><a href="javascript:clickit()">javascript link</a></p>
</body></html>

【讨论】:

【参考方案2】:

您可以做的一个简单的事情是: 从 iframe 页面的 JavaScript 代码执行以下操作

top.location = "https://www.google.co.in/";

这会将窗口 URL 的位置更改为https://www.google.co.in/

还有一件事 - 当您不希望任何人为您的网站添加框架时,此策略也很有用 只需在文档准备部分编写上述代码即可。

【讨论】:

top.location.href = "google.co.in" 为我工作,谢谢 此解决方案不起作用。 Chrome 正在阻止重定向。【参考方案3】:

不,而且有充分的理由。如果需要,则必须通过两台服务器之一运行所有通信;例如,让 server1 充当“server2/test2.html”的所有请求的代理。

【讨论】:

【参考方案4】:

如果父级和 iframe 都位于同一域下的子域上,您可能可以使用 document.domain 属性执行某些操作。如果 body 和 iframe 都被视为来自同一来源,则应该可以更改位置;我自己没有试过这个。一些阅读here

【讨论】:

【参考方案5】:

如果框架在同一个域中,您应该能够访问父框架。否则不行,这是一个安全问题。

想到的唯一解决方法是使用 AJAX 更新每个服务器上的文件,然后在服务器端检查相反文件的内容。如果您允许来自外部域的连接,您可以使用单个数据库执行相同的操作。

不过,这有点矫枉过正,当您可以简单地在框架中弹出一个链接并告诉用户单击它以继续时。

【讨论】:

以上是关于从 IFrame 更改父窗口的 URL的主要内容,如果未能解决你的问题,请参考以下文章

从 IFrame 更改父窗口的 URL

从 iframe 打开一个模态窗口到父窗口

从 iframe 调用父窗口函数

使用 JavaScript 在父窗口中打开 iFrame 表单成功

获得从 iframe 到我无法控制的父窗口 dom 的跨域访问?

如何从跨域 iframe 中访问父窗口的 window.orientation?