如何将postMessage发送到iFrame?

46
我正在开发一款Chrome扩展程序,用于处理加载到我的应用程序主页面上的iframe中(包括跨域页面)的网页。因此,我需要从我的主页面向注入到目标iframe中的内容脚本发送包含要处理页面的URL的消息,以便访问已处理页面的窗口。
我尝试实现这里描述的方法。以下是涉及所有文件的基本部分:

index.html:

...
<head>
    ...
    <script type="text/javascript" src="base.js"></script>
</head>
<body>
    <div>
        <input type="text" id="page_url">&nbsp;<input type="button" id="get_page" value="Get page">
    </div>
    <iframe id="cross_domain_page" src=""></iframe>
</body>

base.js:

(function() {
    "use strict";
    function pageProcessing() {
        let urlButton = window.document.getElementById("get_page");
        urlButton.addEventListener("click", () => {
            let url = window.document.getElementById("page_url").value;
            window.postMessage(
                {
                    sender: "get_page_button1",
                    message: url
                },
                "*"
            );
            window.postMessage(
                {
                    sender: "get_page_button2",
                    message: url
                },
                "*"
            );
        });
    }
    window.document.addEventListener('readystatechange', () => {
            if (window.document.readyState == 'complete') {
                pageProcessing();
            }
        }
    );
})();

manifest.json:

{
  "manifest_version": 2,
  "name": "GetPage",
  "version": "0.1",
  "content_scripts": [
    { "js": ["main.js"], "matches": ["<all_urls>"] },
    { "js": ["frame.js"], "matches": ["<all_urls>"], "all_frames": true, "match_about_blank": true }
  ],
  "permissions": ["activeTab"]
}

main.js:

(function() {
    "use strict";
    window.isTop = true;
})();

frame.js:

(function() {
    "use strict";
    window.addEventListener("message", (event) => {
        if (event.data &&
            event.data.sender == "get_page_button1") {
            if (window.isTop) {
                alert("Main window alert");
            } else {
                alert("Frame window alert 1");
            }
        }
    });
    if (!window.isTop) {
        window.addEventListener("message", (event) => {
            if (event.data &&
                event.data.sender == "get_page_button2") {
                alert("Frame window alert 2");
            }
        });
    }
})();

问题在于当我点击“get_page”按钮时,我只能看到主窗口的警报。据我理解,这意味着从主窗口发布的消息未到达注入到iFrame中的内容脚本。
我的脚本有什么问题,如何解决问题?
1个回答

82

在您的Web应用程序中使用window.postMessage方法时,它会发送到主文档的window,而不是iframe的窗口。

请指定iframe的窗口对象:

document.getElementById('cross_domain_page').contentWindow.postMessage(.......)

或者,您可以切换到更安全的externally_connectable消息传递。


3
根据你的回答,是否意味着要从iFrame发送消息回主窗口,我需要使用类似于“if (!window.isTop) { ... window.parent.postMessage(...); }”的内容? - Kostiantyn Ivashchenko
3
如果跨域的iframe中加载的页面,我是否可以使用postMessage功能?我无法访问其contentWindow。 - Hulk
2
postMessage被设计用于与跨源的iframe / windows一起工作。使用MCVE发布新问题。 - wOxxOm
2
这对我不起作用。iframe 中的监听器没有接收到消息。 - Akhil Ravindran
2
请勿在评论中发表“我也是这样”的内容。请用适当的MCVE提出一个新问题。 - wOxxOm
显示剩余7条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接