从IFrame更改父窗口的URL

时间:2009-12-07 14:57:49

标签: javascript html security iframe

我有一种情况,我在两个不同的服务器上有网络应用程序,其中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" width="400" height="150"></iframe>
</body></html>

服务器2 / 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>

5 个答案:

答案 0 :(得分:13)

好的我做了更多的调查,看来postMessage适用于所有现代浏览器,甚至是IE(需要注意的是,IE的做法略有不同)。以下是我如何使用它(在IE8,FF3.5,Chrome 3.0,Safari 4测试版,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" width="400" height="150"></iframe>
</body>
</html>

服务器2 / 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>

答案 1 :(得分:4)

你可以做的一件简单的事情是: 从iframe页面的JavaScript代码执行以下内容

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

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

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

答案 2 :(得分:2)

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

答案 3 :(得分:1)

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

答案 4 :(得分:0)

如果帧位于同一个域中,您应该能够访问父帧。否则,这是一个安全问题。

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

但是,当你只需在框架中弹出一个链接并告诉用户点击它继续时,这就太过分了。