Reputation: 12852
I need to pass a message (raise an event) in a Chrome extension, and have JavaScript on a web page react to it.
In content_script.js
of the extension, there should be a function like
raiseXYZevent(data);
JavaScript on the web page http://example.com/mypage.html
should execute a handler
function processXYZevent(data) { ... }
The problem is that content script within an extension cannot interact with JavaScript on the web page directly (it can only modify DOM). Is there a way to make DOM changes from the extension, somehow detect them from the web page and call processXYZevent
?
Upvotes: 5
Views: 9173
Reputation: 4537
Since the content script and the webpage share the same DOM, you can use window.postMessage()
to send messages between them. The Chrome API documentation explains this in detail with examples:
Inside the content script, waiting to receive the message:
var port = chrome.runtime.connect();
window.addEventListener("message", (event) => {
// We only accept messages from ourselves
if (event.source !== window) {
return;
}
if (event.data.type && (event.data.type === "FROM_PAGE")) {
console.log("Content script received: " + event.data.text);
}
}, false);
Inside the page (this also includes code you have injected into the page via chrome.scripting.executeScript()
or similar), sending a message when a button is clicked:
button.addEventListener("click", () => {
window.postMessage({
type : "FROM_PAGE",
text : "Hello from the webpage!"
}, "*");
}, false);
The docs above mention:
The reverse is possible through similar means.
To do this, simply swap the content script code and the page code in the examples above.
Upvotes: 6
Reputation: 400
From content script inject this:
$('html').append(`
<script>
window.addEventListener("message", function(event) {
// We only accept messages from ourselves
if (event.source != window)
return;
if (event.data.type && (event.data.type == "FROM_CONTENT")) {
console.log("Page script received: " + event.data.text)
console.log(event.data.text) // "Something message here"
}
}, false)
<\/script>`)
In content script you can execute this:
window.postMessage({ type: "FROM_CONTENT", text: "Something message here"}, "*")
Upvotes: 1