dbkk
dbkk

Reputation: 12852

Pass a message from Chrome Extension to Webpage

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

Answers (2)

Matthew Gertner
Matthew Gertner

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:

Posting a message from the page to the extension

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);

Posting a message from the extension to the page

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

Hender
Hender

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

Related Questions