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
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-scriptvar 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);
webpagewindow.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
JavaScript Object Literals Syntax Error
Regular Expression to Match Exactly 5 Digits
Using Raw Image Data from Ajax Request for Data Uri
Javascript: Uploading a File... Without a File
Mongoose, Select a Specific Field with Find
Add Commas to a Number in Jquery
Why and When to Use Default Export Over Named Exports in Es6 Modules
How to Avoid Freezing the Browser When Doing Long-Running Computations in JavaScript
How to Add My Own Methods to HTMLelement Object
C# Web Method Is Not Calling in JavaScript
React-Router Getting This.Props.Location in Child Components
Escaping Backslash in String - JavaScript
Why a Variable Defined Global Is Undefined
JavaScript Call Nested Function
How to Upload Preview Image Before Upload Through JavaScript
Get Width Height of Remote Image from Url
JavaScript Roundoff Number to Nearest 0.5
How to Subscribe to Topics with Web Browser Using Firebase Cloud Messaging