【问题标题】:Changing parent window's URL from IFrame从 IFrame 更改父窗口的 URL
【发布时间】: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" 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>

【问题讨论】:

    标签: javascript html security iframe


    【解决方案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" 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>
    

    【讨论】:

      【解决方案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 更新每个服务器上的文件,然后在服务器端检查相反文件的内容。如果您允许来自外部域的连接,您可以使用单个数据库执行相同的操作。

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

          【讨论】:

            猜你喜欢
            • 2014-06-17
            • 1970-01-01
            • 1970-01-01
            • 2012-06-27
            • 2019-01-28
            • 2015-02-15
            • 1970-01-01
            • 2012-05-08
            • 2012-04-06
            相关资源
            最近更新 更多