Ways to send a message from a chrome extension to a webpage and patiently await a reply

Currently, I'm exploring ways to send messages from a Chrome extension to a page view and wait for a response. Here's what I've tried so far:

In the extension's content_script.js:

window.addEventListener('message', function(event) {
    console.log('content_script.js got message:', event);
    // Check event.type and event.data
});

setTimeout(function () {
    console.log('cs sending message');
    window.postMessage({ type: 'content_script_type',
                         text: 'Hello from content_script.js!'},
                       '*' /* targetOrigin: any */ );
}, 1000);

The Javascript running on the webpage:

window.addEventListener('message', function(event) {
    console.log('page javascript got message:', event);
});

setTimeout(function() {
    console.log('page javascript sending message');
    window.postMessage({ type: 'page_js_type',
                         text: "Hello from the page's javascript!"},
                       '*' /* targetOrigin: any */);
}, 2000);

Reference: Chrome extension - retrieving global variable from webpage

However, I discovered that using window.postMessage results in one-way communication and does not allow waiting for a response. Any ideas on how to achieve this?

Answer №1

One way to handle messaging synchronously is by using dispatchEvent and CustomEvent, as demonstrated in the example you provided. This method allows for a simple setup for message passing in both directions. It's important to note that synchronous communication is not inherently inferior, especially in this case where dispatchEvent is much simpler internally compared to postMessage, which is primarily used for cross-process and cross-origin communication.

The content script (or invoker) can implement this approach:

let response;
addEventListener('yourUniqueEventIdFromPage', e => {response = e.detail}, {once: true});
dispatchEvent(new CustomEvent('yourUniqueEventIdFromContent', {detail: 'foo'}));
console.log(response); // demonstrates synchronous code execution

The page script (or responder), on the other hand, should listen for events and respond accordingly:

addEventListener('yourUniqueEventIdFromContent', e => {
  const fromContent = e.detail;
  const result = 'do something to get results';
  dispatchEvent(new CustomEvent('yourUniqueEventIdFromPage', {detail: result}));
});

It is advised against using window.postMessage in extension content scripts due to security concerns. The unpredictable nature of this method could lead to unintended consequences, such as breaking functionality on certain sites. To mitigate these risks, consider alternatives such as the approach outlined above. Keep in mind that there may still be limitations due to underlying browser architectures, so caution is always recommended.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Experiencing discrepancies in pixel height while conducting tests using Nightwatch

Let me start by sharing some details about my machine setup: Operating System: CentOS 7 Graphics Drivers: kmod-nvidia (dedicated GPU) I am currently testing a webpage using Nightwatch, and one of the requirements is to ensure that a background image&apo ...

Is it possible to transmit a WebRTC frame to a Python script?

I recently built my first web app using Python and Django, which displays webcam frames of clients. 'use strict'; // For this project, I am only streaming video (video: true). const mediaStreamConstraints = { video: true, }; // Video element ...

Capturing and saving detailed hand-drawn artwork in high resolution

Is there a cutting-edge solution available for capturing hand-drawn sketches (from a tablet, touch screen, or iPad-like device) on a website using JavaScript and saving it on the server side? Essentially, I am looking for a mouse drawing canvas with a hig ...

retrieve JSON object from deferred response of AJAX request

After utilizing Ajax to send an item to a SharePoint list, I aim to incorporate the jsonObject received in response into a list of items. Located in AppController.js $scope.addListItem = function(listItem){ $.when(SharePointJSOMService.addListIte ...

Updating Content with Javascript: A Step-by-Step Guide

How can we modify the function show(question, answer) to handle single quotes? function updateText(post) { let newQuestion = post.question.replace(/'/g,'\\''); let newAnswer = post.answer.replace(/'/g, ...

Exploring the power of jQuery and Ajax together

Today seems to be one of those days where even the simplest tasks become a challenge. I'm sorry if this question has been asked before, but I'm struggling with a basic issue. I want to dynamically update text on a website using a text file, and w ...

What is the best way to showcase a table below a form containing multiple inputs using JavaScript?

Context: The form I have contains various input fields. Upon pressing the [verify] button, only the "first name" is displayed. My goal is to display all input fields, whether empty or filled, in a table format similar to that of the form. Exploration: ...

Add Content to Textbox by Clicking

In my current setup, I have a variety of buttons that, when clicked, should add the text from the button to a text box. Each time a button is clicked, I want the text to be appended to whatever is already in the input field. Current Approach $('#js- ...

Share an entire /folder through an express server

I am currently working on an express server setup, and I am looking to streamline my route handling for managing an entire directory structure. root /html /css /js /app.js /images /index.html /some-other.htm ...

Adding a JavaScript file to another JavaScript file

Is there a way to embed one JavaScript file into another so that it can be referenced? I'm looking for the JavaScript equivalent of include() in PHP. Many people have suggested using this method: document.write('<script type="text/javascript ...

Is it possible for arrow functions to be hoisted within a class in JavaScript?

class App { constructor() { this.canvas = document.createElement('canvas'); document.body.appendChild(this.canvas); this.ctx = this.canvas.getContext('2d'); this.pixelRatio = window.devicePixelRatio > 1 ? 2 : 1; ...

What is the best way to extract data from a JSON object in JavaScript?

let result = JSON.parse(data.d); The current code doesn't seem to be working.. Here is the structure of my JSON object: [{"ItemId":1,"ItemName":"Sizzler"},{"ItemId":2,"ItemName":"Starter"},{"ItemId":3,"ItemName":"Salad"}] Any suggestions on how I ...

The child user interface component is failing to respond to keypress events within the parent component in an Angular project

I am facing a challenge in adding a keyboard shortcut to open a nested child UI Tab component through a keypress event. However, the Child nested tab can only be loaded after the Parent component is loaded first. Below is the structure of the UI tree: |-- ...

Moving Configuration Files in NextJS

When working on a typical Next.js project, I often end up with several root-level configuration files: tsconfig.json next.config.js next-seo-config.ts .eslintrc etc... I am looking to tidy up my root directory by moving these files into their own separat ...

What is the best way to deliver an HTTP request from the controller to my Ajax function?

Is there a way to send HTTP OK and error responses from the controller to my AJAX request? For example, using HttpStatusCode.OK and HttpStatusCode.BadRequest. When I inspect in my browser it shows impresion.js 304 not modified. $(document).ready(functi ...

Developing a Chessboard Using JavaScript

Seeking help with a Javascript chessboard project. I have successfully created the board itself, but facing difficulty assigning appropriate classes (black or white) to each square. Managed to assign classes for the first row, struggling with the remainin ...

Scrolling triggers Navbar Hover for all links

Currently, I am utilizing a free html5 theme as a foundation for a website project, but I require assistance with the Navbar Hover function. If you wish to see the original html5 theme, you can visit The theme was initially designed as a one-page layout, ...

Mocha test failing to trigger function execution

I've been developing an Express.js application that includes a feature for creating appointments with a post request. This feature involves retrieving and saving data from a third-party API, followed by sending updated API data in the subsequent reque ...

What are the steps to run and test the renovate bot on your local machine

Before setting up renovate to work with my Azure pipeline, I wanted to test it locally using npx renovate to ensure everything is working as expected and that my config file is properly configured. I ran npx renovate --platform local command. My project i ...

Obtaining an address using latitudes and longitudes with React Google Maps

I created a map using the react-google-map plugin where users can drag the marker to get the latitude and longitude of a location. However, I am only able to retrieve the lat and lng values and not the address. How can I obtain the address as well? Take a ...