Home > Back-end >  How to communication from chrome extension to webpage and can wait for response
How to communication from chrome extension to webpage and can wait for response

Time:10-01

I trying to find a solution send message from Chrome extension to page-view and can wait for response.

I had try: 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);

ref: Chrome extension - retrieving global variable from webpage

but I found window.post it's one-way communication it can't wait for response.

any Idea?

CodePudding user response:

Use dispatchEvent CustomEvent as shown in the example you've linked because it's synchronous so you can simply do the same messaging setup additionally in reverse. Note that synchronous doesn't mean worse in general and certainly not here as dispatchEvent is much simpler internally than postMessage, which is designed to handle cross-process cross-origin communication.

Invoker (content script in your case):

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

Responder (page script in your case):

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

P.S. Don't use window.postMessage in an extension content script to communicate with your page script. It's dangerous, because you could break some site with a message it doesn't expect in its own listener, which can also see and even intercept your message. An imperfect solution is to set your content script to run at document_start, immediately add a listener for message event, which calls event.stopImmediatePropagation(). There's no perfect solution though due to an architectural bug in Chrome and other browsers that allows the sites to spoof the JS environment of same-origin child frames or pages. There's a workaround used by Tampermonkey/Violentmonkey but it's very complex and thus wastes time during page load, insignificant in their case, though.

  • Related