I am developing a Chrome extension to use with my own Web-application, processing Web-pages (including cross-domain ones), loaded into iFrame
on my application's main page. So I have to send message, containing the URL of the page to be processed, from my main page to the content script, injected into the target iFrame
to get access to the processed page's window.
I try to implement the approach, described here. Below are the essential parts of all files involved:
index.html
:
...
<head>
...
<script type="text/javascript" src="base.js"></script>
</head>
<body>
<div>
<input type="text" id="page_url"> <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");
}
});
}
})();
The problem is that when I click "get_page" button the only alert I see is the main window alert. As for my understanding it means that the message, posted from the main window, does not reach the content script, injected into iFrame
.
What is wrong with my script and how to fix the problem?
Communicating directly between iframes is also possible by combining window. parent with target as defined above. In conclusion, the postMessage method is a more dynamic alternative to the single DOM, better suited if you load multiple pages in one iframe, but not always easier and it still requires the use of the DOM.
In action: iframeAn <iframe> tag hosts a separate embedded window, with its own separate document and window objects.
window.postMessage in your web app sends to the main document's window
, not to the iframe's.
Specify the iframe's window object:
document.getElementById('cross_domain_page').contentWindow.postMessage(.......)
Alternatively, you can switch to the more secure externally_connectable messaging.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With