Gmail Extension, Sendmessage to Background from Page Context

Gmail Extension, sendMessage to background from page context

A page-context script cannot, indeed, use Chrome API.

It can, however, dispatch DOM events that can be caught by the content script.

There is an example in the documentation here. Besides using window.postMessage, you can dispatch custom events.

So, you need to make your content script to work like a proxy between page context and background. Something along these lines:

// Content script
//Listen for the event
window.addEventListener("PassToBackground", function(evt) {
chrome.runtime.sendMessage(evt.detail);
}, false);

// Page context
var message = {/* whatever */};
var event = new CustomEvent("PassToBackground", {detail: message});
window.dispatchEvent(event);

You can generalize this to pass an answer back.

Using postMessage to extension background page

Thanks to the comment by @wOxxOm I solved it by creating a web accessible resource with this code:

window.addEventListener("message", receiveMessage, false);

function receiveMessage(event) {
chrome.extension.getBackgroundPage().postMessage(event.data, "*");
}

This is triggered by the contentscript like that:

let iframe = document.createElement('iframe');
iframe.setAttribute('src', chrome.extension.getURL('webaccessible/index.html'));
iframe.addEventListener("load", () => {
iframe.contentWindow.postMessage(data);
})

While data is an object that contains the CryptoKey.

This data is received in the background script just like you normally would receive such messages:

window.addEventListener('message',(event) => {
console.log(event);
});

Chrome extension, best way to send messages from injected script to background

Your injected.js is running in a script DOM element so it's just an unprivileged web page script. To use chrome.runtime.sendMessage directly from a web page script you would have to declare the allowed URL patterns in externally_connectable but you can't allow all URLs indiscriminately so I would use your approach, although with a CustomEvent (and a random event name most likely) instead of message which can be intercepted by the page scripts or other extensions - it's not security that I'm concerned with here, but rather a possibility of breaking some site that assumes the message data is in a certain format (e.g. string), not compatible with the one you use (e.g. object).

You can also use chrome.debugger API to attach to the tab and intercept the JSON response in your background script, but that will show a notification above the tab about it being debugged.

Anyway, unless you see your extension slowing down the page (in devtools profiler or by manually measuring the time spent in your code), there's no need to worry.

FWIW, in Firefox you can read the response directly via browser.webRequest.filterResponseData.

Can I post messages from page directly to extension's background script w/o content-script in chrome?

Thanks to @wOxxOm @rsanchez I should:

  • Use chrome.runtime.onMessageExternal in background.js
  • Add externally_connectable to manifest.json

https://localhost:8000:

var port = chrome.runtime.connect("ppibnonicgkeojloifobdloaiajedhgg"); 
port.onMessage.addListener(function (event) {
console.log(event);
});
port.postMessage({type: 'PYCHAT_SCREEN_SHARE_PING', text: 'start'});

manifest.json

{
"name": "test",
"description": "test",
"version": "1.0.0",
"manifest_version": 2,
"background": {
"scripts": ["background.js"]
},
"permissions": [
"desktopCapture",
"tabs"
],
"externally_connectable": {
"matches": ["https://localhost:8000"]
}
}

background.js:

chrome.runtime.onConnectExternal.addListener(function(port) {
port.onMessage.addListener(function(msg) {
console.log("it works")
port.postMessage({type: "PYCHAT_SCREEN_SHARE_PING_RESPONSE", data: "successs"});
});
});

Firefox Addon - Send message from webpage to background script

You can communicate with background.js from webpage through content-script. Try this:

background.js

chrome.runtime.onMessage.addListener(
function(request, sender, sendResponse) {
if (request.hello) {
console.log('hello received');
}
});

content-script

var port = chrome.runtime.connect();

window.addEventListener("message", function(event) {

if (event.source != window)
return;

if (event.data.type && (event.data.type == "FROM_PAGE")) {
console.log("Content script received: " + event.data.text);
chrome.runtime.sendMessage({
hello: 1
});
}
}, false);

webpage

window.postMessage({ type: "FROM_PAGE", text: "Hello from the webpage!" }, "*");

How to dynamically send chrome extension ID to a webpage for message passing

First off, if you already have a content script, you don't have to use externally_connectable to communicate - you could use custom events to communicate with the content script that would forward it to background.


That said, you can use chrome.runtime.id and pass it to the window context before injecting your script:

var script = document.createElement('script');
script.textContent = "var extensionId = " + JSON.stringify(chrome.runtime.id);
(document.head||document.documentElement).appendChild(script);
script.parentNode.removeChild(script);

/* now inject your script */

Alternatively, you could add an invisible DOM node that would contain the ID as content or some attribute and read that from the injected script.

sending message to chrome extension from a web page

According to the official docs you should use postMessage in the sender and message event listener in the receiver.

Here is an example:

Your website's page.html

var data = { type: "FROM_PAGE", text: "Hello from the webpage!" };
window.postMessage(data, "*");

Content script: (injected using chrome.tabs.executeScript(tabid, {code:...)

window.addEventListener("message", function(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 message: " + event.data.text);
}
});

Here page.html (which is not a part of the extension) posts messages to itself, which are intercepted and inspected by the content script. The reverse is possible through similar means.

To pass from content script to extension, you will have to use one of the available message-passing techniques.

It looks complicated and it is somewhat complicated but all this mumbo-jumbo is very secure.



Related Topics



Leave a reply



Submit