sending message to chrome extension from a web page

Multi tool use
Multi tool use


sending message to chrome extension from a web page



I want to send message from the console of the random web page to my chrome extension.
chrome.extension.sendMessage doesn't seem to work.




5 Answers
5



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


postMessage


message



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:...)


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.


page.html



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.





can I try to insert the code in the Website's html for dispatching event along through the 'chrome.tabs.executeScript()' command? I tired that and it isn't working... it says, "Port Error: could not establish connection: receiving end does not exist:
– dilpreet023
Jul 11 '12 at 13:16






Thanks for this. I was wondering how to do this more securely than just window.postMessage. This would definitely have fewer side effects, but still unfortunately could be tampered with by a malicious web page. I'm looking forward to chrome.runtime.onMessageExternal which will allow a somewhat more secure (hopefully) channel of communication
– kzahel
Aug 17 '13 at 13:23






@kzahel Content scripts are ran within their own context, so it's isolated from webpage context. Content scripts have access to the DOM (the HTML elements), basically you can attach listeners if you want to pass data between contexts, you can do that via events. Just note there are 3 different contexts: Extension, Custom script, and webpage scripts.
– Silviu-Marian
Feb 5 '14 at 15:01






That first link mentions using windows.postMessage(...) so apparently you don't even need a custom myCustomEventDiv, as it were...
– rogerdpack
Jan 24 '17 at 18:18


windows.postMessage(...)





Glad to find this after an hour of searching. Thanks for the writeup!
– Dan Abramov
Apr 28 '17 at 14:53



Here's a quote from the latest http://developer.chrome.com/extensions/messaging.html, It's much simpler to support this kind of feature now, here's how:



Similar to cross-extension messaging, your app or extension can
receive and respond to messages from regular web pages. To use this
feature, you must first specify in your manifest.json which web
sites you want to communicate with. For example:


manifest.json


"externally_connectable": {
"matches": ["*://*.example.com/*"]
}



This will expose the messaging API to any page which matches the URL
patterns you specify. The URL pattern must contain at least a
second-level domain - that is, hostname patterns like "", ".com",
".co.uk", and ".appspot.com" and <all_urls> are prohibited.
From the web page, use the runtime.sendMessage or runtime.connect APIs
to send a message to a specific app or extension. For example:


// The ID of the extension we want to talk to.
var editorExtensionId = "abcdefghijklmnoabcdefhijklmnoabc";

// Make a simple request:
chrome.runtime.sendMessage(editorExtensionId, {openUrlInEditor: url},
function(response) {
if (!response.success)
handleError(url);
});



From your app or extension, you may listen to messages from web pages
via the runtime.onMessageExternal or runtime.onConnectExternal APIs,
similar to cross-extension messaging. Only the web page can initiate a
connection. Here is an example:


chrome.runtime.onMessageExternal.addListener(
function(request, sender, sendResponse) {
if (sender.url == blacklistedWebsite)
return; // don't allow this web page access
if (request.openUrlInEditor)
openUrl(request.openUrlInEditor);
});





This works for me. However, I have one question. How do people find the ID of their extension? At the moment I just hard code it.
– user1311069
Feb 19 '14 at 17:57





how to see that message is received by extension, I'm using unpacked extension. I'm currently developing it.
– pavan
Sep 24 '14 at 13:43





@user1311069 the extension ID generation mechanism is explained here: stackoverflow.com/a/21500707/258772
– mrts
Jan 2 '15 at 18:01






This should be the accepted answer.
– sbichenko
Jun 7 '15 at 18:42





Listen to events with chrome.runtime.onMessageExternal.addListener()
– sbichenko
Jun 12 '15 at 13:59


chrome.runtime.onMessageExternal.addListener()



You can switch to the JS execution context of your content script using the <page context> menu at the bottom of a page’s developer JS console, then use chrome.runtime.sendMessage and other chrome.* APIs just as you would within the content script.


<page context>


chrome.runtime.sendMessage


chrome.*



enter image description here





What can be the reason if the execution context switching menu shown in your screenshot does not appear (Chrome v 39.0.2171.95 m, Windows 7)?
– mrts
Jan 2 '15 at 19:36





Just for reference - I can access the extension context console by opening the extensions page (chrome://extensions) and clicking the Inspect views: background page link, so the missing context switching menu is not a big problem really.
– mrts
Jan 2 '15 at 19:43



chrome://extensions





In a recent release, Chrome combined the execution context menu with the frame menu. If your extension has a content script in the page, you should now see it listed under <top frame>.
– jaredjacobs
Jan 3 '15 at 21:28


<top frame>





Thanks for the tip. Unfortunately I only see <top frame> when I click on the drop-down, even though the page script is able to communicate with the extension with no problems. But as I can use the background page link from the extensions page, it's just a cosmetic issue.
– mrts
Jan 4 '15 at 17:44



<top frame>





@mrts Background script != Content script. There are 3 separate JS execution contexts here: page script (what you see in your console by default), background script (what you see when you inspect the background page and is universal [one instance] for all Chrome tabs), and content script, which runs inside a given tab + given url as defined in manifest.json. If you put window.foo = 'bar'; in a content script, you won't see it in the background-page-inspection console. afaics it's only viewable via the dropdown that jaredjacobs points out here (which is now under 'top').
– jdunk
Mar 28 '17 at 7:58


window.foo = 'bar';



So to elaborate, a more concreate example: An issue with chrome.runtime.sendMessage(...) style is that you have to specify the pag you're on as externally_connectable which doesn't take a global wildcard like "https:///". So if you want that ability, you have to use the postMessage style communication. Capture the message from the window into the contentscript, then from the contentscript, you can send it elsewhere (if desired, like to the background.js etc.)


chrome.runtime.sendMessage(...)


postMessage


contentscript


contentscript


background.js



So in the normal web page, or in injected source that you embed into the normal page, from your contentscript.js, send a message like this:


contentscript.js


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



ex, you could add it to a button like this:


document.getElementById("theButton").addEventListener("click",
function() {
window.postMessage({ type: "FROM_PAGE_TO_CONTENT_SCRIPT",
text: "Hello from the webpage!" }, "*");
}, false);



Then to capture it in the contentscript.js and "send it on" to the rest of the extension, the only caveat is that you only want to "select" messages that seem to be ones that you care about:


window.addEventListener("message", function(event) {
// We only accept messages from this window to itself [i.e. not from any iframes]
if (event.source != window)
return;

if (event.data.type && (event.data.type == "FROM_PAGE_TO_CONTENT_SCRIPT")) {
chrome.runtime.sendMessage(event.data); // broadcasts it to rest of extension, or could just broadcast event.data.payload...
} // else ignore messages seemingly not sent to yourself
}, false);



In addition to @hewigovens , I don't have enough points to comment...
I'm explaining @renatoargh and @sbichenko
If sending message from a default web page -



1) the webpage needs to be quoted in the manifest. e.g.:


"externally_connectable": {
"matches": ["http://abcde/abcde/main.aspx*"]
}



2) the background.js (background page)
excepts the call with onMessageExternal e.g. (calling an extension):


var host_name = "com.my_chrome_extension.com";
chrome.runtime.onMessageExternal.addListener(function(message, sender, sendResponse) {
chrome.runtime.sendNativeMessage(host_name, {"run":message});
sendResponse({"success": "success"});
return true;
});




Thank you for your interest in this question.
Because it has attracted low-quality or spam answers that had to be removed, posting an answer now requires 10 reputation on this site (the association bonus does not count).


Would you like to answer one of these unanswered questions instead?

ialmfLexn9jotOX4b5S8x zghfxoc KapvpUiz6,CIfQ,ZZL 5I1c TX
qhQHofpiVYbV,sW2vnV,jXNAOpbZLAHluy2vIqzpmNhtIhVHdEP2t 7nS CPgth,4 a Xfg0,Yzm7hwq4,o

Popular posts from this blog

Rothschild family

Cinema of Italy