如何在同一域的IE8中访问嵌套框架的location.href?

时间:2018-01-11 12:49:50

标签: javascript internet-explorer iframe internet-explorer-8 frameset

我的主页包含一个<iframe>,指向包含<frameset>的HTML文件。它看起来与以下类似(为便于阅读而简化):

<html>
<body>
  <iframe id="content" src="/same/domain/url" />
</body>
</html>

<iframe>内容如下所示:

<html>
<body>
  <frameset>
    <frame name="menu" src="/same/domain/menu/url" />
    <frame name="main" src="/same/domain/initial/main/url" />
  </frameset>
</body>
</html>

我正在尝试从主页面读取main框架的当前位置href。

$("#content").contents().find("frame[name=main]")[0].contentWindow.location.href

不幸的是,在IE8上它给了我&#34; Permission denied&#34;错误。这看起来像跨域脚本防止机制,但所有URL都来自相同的域/协议/端口。对于相同的JavaScript代码,Chrome为我提供了正确的价值(惊喜,惊喜)。

请注意:

  • 我无法使用框架的src属性,因为用户可能已经使用过&#34;菜单&#34;框架导航到另一个页面(仍然是同一个域)。
  • 我无法控制iframe页面的内容,这些内容由应用程序的其他部分提供,从我的角度来看是不可修改的

我该如何解决这个问题?

1 个答案:

答案 0 :(得分:1)

执行此操作的方法是使用postMessage api,允许在不同的窗口/帧之间传递消息。

在根窗口中,侦听消息

window.attachEvent("onmessage", (e) => {

    // handle message

});

将消息发布到子帧(iframe是dom节点)。

iframe.contentWindow.postMessage({}, "*");

在孩子中

window.parent.postMessage({}, "*");

这允许一种简单的事件驱动通信方案,您可以以消息的形式发送操作并接收响应时间 作为onmessage事件。

在你的情况下,你会有所作为:

// within child iframe
window.attachEvent("message", function (e) {
    // IE8 does not support object passing, only strings
    var message = JSON.parse(e.data);

    // wait for a GET_HREF message
    // and respond to it with the
    // data.
    if (message.type === "GET_HREF") {
        window.parent.postMessage(JSON.stringify({
            type: "GET_HREF",
            data: $("frame")
                .map(function () {
                    return this.href;
                })
                .get()
        }));
    }
});


// within parent window
window.attachEvent("message", function (e) {
    // IE8 does not support object passing, only strings
    var message = JSON.parse(e.data);

    // wait for a GET_HREF message
    if (message.type === "GET_HREF") {
        updateHref(message.data);
    }
});

iframe.contentWindow.postMessage(JSON.stringify({
    type: "GET_HREF"
}), "*");