My overall goal was to take a screenshot via the background page using:
http://developer.chrome.com/extensions/tabs.html#method-captureVisibleTab
and pass it to the content script so I can use the page's HTML DOM to analyze the screenshot and cut it up the way I would like.
However, I can't seem to pass the dataUrl back to the content script with Message Passing:
http://developer.chrome.com/extensions/messaging.html
I tried JSON.stringify() but to no avail.
This works perfectly fine:
background.js
chrome.runtime.onMessage.addListener(
function(request, sender, sendResponse) {
sendResponse({imgSrc:'hello'});
}
);
I switch the code to this and nothing gets through:
background.js
chrome.runtime.onMessage.addListener(
function(request, sender, sendResponse) {
chrome.tabs.captureVisibleTab(
null,
{},
function(dataUrl)
{
sendResponse({imgSrc:dataUrl});
}
)
}
);
My only proof that the background page is actually taking a screenshot is that I can do
chrome.tabs.captureVisibleTab(null,{},function(dataUrl){console.log(dataUrl);});
and I see
"data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAA....etc..."
logged in background.html, which is valid
My question is: How can I send this URL to the content script?
I would prefer not to do all the logic on the background page which can't control anything on the actual visible page.
Use chrome.tabs.sendMessage and make sure to return true, not the event listener
background page:
chrome.runtime.onMessage.addListener(
function(request, sender, sendResponse) {
chrome.tabs.captureVisibleTab(
null,
{},
function(dataUrl)
{
sendResponse({imgSrc:dataUrl});
}
);
return true;
}
);
content script
chrome.runtime.sendMessage({msg: "capture"}, function(response) {
console.log(response.dataUrl);
});
Related
Example: I have created safari extension, which, after the page loads, replaces all words "fish" with the fish emoji. I want to count how many words I replaced and store that number (total number of replaces since installing the extension). When I click on the extension icon in toolbar, I want to see that total number.
content.js handles the replacing
popup.js handles the toolbar icon menu
I only need the storing capability implemented, so I need a function in content.js called SomehowStoreThisValue() and in popup.js function SomehowRetrieveThisValue()
What I've tried: (Using the local storage)
content.js:
browser.runtime.sendMessage({
data: "Hello popup, how are you"
}, function (response) {
console.dir(response);
});
popup.js:
browser.runtime.onMessage.addListener(function (message, sender, sendResponse) {
sendResponse({
data: "I am fine, thank you. How is life in the background?"
});
let my_value = parseInt(localStorage.getItem('stored_value'));
document.getElementById("MY_ID").innerHTML = my_value;
localStorage.setItem('stored_value', my_value + 1);
});
Which does work, but only when the popup is open, when the replacement is happening, which is not ideal.
I am able to pass data from my webpage to chrome extension. My code goes as follows.
var id = "myExtensionId";
chrome.runtime.sendMessage(id, { messageFromWeb: "Sample message" }, function (response) {
});
I am able to get the tab Id at the extension side. But how can I send back data from the extension to the tab? Is the following code correct?
chrome.runtime.onMessageExternal.addListener(
function(request, sender, sendResponse) {
if (request.messageFromWeb) {
console.log(request.messageFromWeb);
}
chrome.tabs.sendMessage(sender.tab.id,{ greeting: "hello" });
}
);
The code, chrome.tabs.sendMessage(sender.tab.id,{ greeting: "hello" }); does not throw error.
How should be listening at the web page to get events from extension?
From content script to website script
Because the content script and the scripts in the website can see the same DOM, you can use it to communicate between them. Is as easy as:
Content script:
// data you want to sent
var data = {
random: 'Some data',
more: 'More data'
};
// send data through a DOM event
document.dispatchEvent(new CustomEvent('csEvent', {detail: data}));
Website script:
// Listen you CRX event
document.addEventListener('csEvent', function (event) {
var data = event.detail;
// Do something with you data from CRX
});
From content script to background script
How to do it depends on which type of connection you need: one-time or long-lived. From Chrome Developer page Messaging:
There is a simple API for one-time requests and a more complex API that allows you to have long-lived connections for exchanging multiple messages with a shared context.
If you only want to send a response back, here is an example:
chrome.runtime.onMessage.addListener(
function(request, sender, sendResponse) {
console.log(sender.tab ?
"from a content script:" + sender.tab.url :
"from the extension");
sendResponse({farewell: "Message back!"});
});
Edited to add content script to website script way
i'm trying sending data from website javascript to my chrome extension.
I read about sending msgs from website and i couldn't make it work.
in my website:
$("#button-id").click(function(){
chrome.runtime.sendMessage("msg", {arg: "1"},
function(response){alert("got response: " + response);});
});
and in background.js (in the chrome extension)
chrome.runtime.onMessageExternal.addListener(
function() {
alert("in background");
return "1";
});
I also added to the manifest:
"externally_connectable": {
"matches": ["*://localhost/project/public/*","http://localhost/project/public/*","*://*/*/*"]
},
and all I'm getting when I'm clicking that button is alert that says "got response undefined".
something that i tried that maybe will help to figure it out:
when I'm on my website, opening chrome developer console, typing "chrome.runtime.sendMessage("jjj");"
I'm getting 'undefined'.
thanks in advance!!!
To send a response, you need to pass it to sendResponse parameter of the listener, which is the third parameter:
chrome.runtime.onMessageExternal.addListener(
function(message, sender, sendResponse) {
alert("in background");
sendResponse("1");
}
);
One thing to note: if sendResponse is going to be called asynchronously, you have to return true;
Also, when sending a message from a webpage, you have to supply the extension's id as the first parameter. In your example code it's "msg": it must be an extension id.
I have a chrome extension that sets a string value in JavaScript localStorage in a content script. I have tested that it is being set by grabbing it and displaying it. While on the same page after it has loaded I can still access the stored string in the javascript console. If I go to any other tabs js console or when I try to access it in my other extensions background page(After the browser action has been clicked) it is returning null.
extension 1 contentscript.js
embeded.addEventListener
(
"message",
function(message)
{
localStorage.setItem("pdf", message.data);
loadPDF(message.data);
},
false
);
extension 2 background.js
chrome.browserAction.onClicked.addListener(function(tab) {
if (tab.url.substr(tab.url.length - 4) === ".pdf")
{
if (localStorage.getItem("pdf") !== null)
{
alert("boomy");
}
}
});
localStorage is shared among extension pages (background, options, popup), but not content scripts. And most certainly not shared between 2 extensions!
You have two-and-a-half options. With 2 separate extensions, only one option.
Option one: rely on messaging.
When you need to pass some value between background and content script, you can do so with messaging. Works especially well if you only need to pass it in one direction.
contentscript.js:
embeded.addEventListener(
"message",
function(message)
{
chrome.runtime.sendMessage(extensionTwoId, {pdf: message.data});
loadPDF(message.data);
},
false
);
background.js:
chrome.runtime.onMessageExternal.addListener(
function(message, sender, sendResponse) {
if(sender.id !== extenstionOneId) return;
if(message.pdf) localStorage.setItem("pdf", message.pdf);
}
);
/* ... */
Option two: chrome.storage. Not applicable between 2 extensions.
I try to create a communication channel between specific webpage (per example : www.website.dev) and a chrome extension I created.
By using postMessage it's work from webpage to extension but I can't do that from extension to webpage.
I tried Google example but it uses background page
Thanks for your help
EDIT : sorry I don't understand the difference between content_script and background.js
In my manifest I have content script = test.js
What's about "background" ?
Following the documentation you can pass messages to your extension if you know the extension id:
https://developer.chrome.com/extensions/messaging#external-webpage
manifest.json
"externally_connectable": {
"matches": ["*://*.example.com/*"]
}
website:
// 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);
});
extension:
chrome.runtime.onMessageExternal.addListener(
function(request, sender, sendResponse) {
if (sender.url == blocklistedWebsite)
return; // don't allow this web page access
if (request.openUrlInEditor)
openUrl(request.openUrlInEditor);
});
You will find all the details in the documentation https://developer.chrome.com/extensions/messaging
You would have one piece use sendMessage function while the other piece is listening for the event, which could be either a webpage or content script.
either the webpage's content script should initiate the communication (so you would get the tab id) or you can have the background query for tabs with specific url and then use sendMessage. Notice two separate functions chrome.extension.sendMessage and chrome.tabs.sendMessage used here.
the following code works for me:
content_script.js:
chrome.extension.sendMessage({"msg":"hello"});
background.js:
chrome.extension.onMessage.addListener(function (request, sender, sendResponse) {
if (request.msg == "hello"){
senderTab = sender.tab.id;
chrome.tabs.sendMessage(senderTab, {"msg": "ehlo"});
};
})