我遇到的情况是,我在两个不同的服务器上都有Web应用程序,其中App1在IFrame中包含App2。 App2中的任何链接都可以具有target="_parent"
属性,该属性允许这些链接在顶部窗口中打开。但是,我找不到在Javascript中获得相同行为的任何方法。我发现this page,它声称子框架可以使用parent.foo()
在父框架上调用javascript,但是在IE8或FF3.5中似乎不起作用。我发现this SO question解释了此安全模型的工作原理。但是,我无法用Java脚本实现像使用简单的<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>
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>
最佳答案
好的,我进行了更多调查,似乎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" width="400" height="150"></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>