Pass data from chrome extension to webpage - javascript

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

Related

How to get Chrome Extension's Options value in Extension? [duplicate]

I have an options page where the user can define certain options and it saves it in localStorage: options.html
Now, I also have a content script that needs to get the options that were defined in the options.html page, but when I try to access localStorage from the content script, it doesn't return the value from the options page.
How do I make my content script get values from localStorage, from the options page or even the background page?
Update 2016:
Google Chrome released the storage API: https://developer.chrome.com/docs/extensions/reference/storage/
It is pretty easy to use like the other Chrome APIs and you can use it from any page context within Chrome.
// Save it using the Chrome extension storage API.
chrome.storage.sync.set({'foo': 'hello', 'bar': 'hi'}, function() {
console.log('Settings saved');
});
// Read it using the storage API
chrome.storage.sync.get(['foo', 'bar'], function(items) {
message('Settings retrieved', items);
});
To use it, make sure you define it in the manifest:
"permissions": [
"storage"
],
There are methods to "remove", "clear", "getBytesInUse", and an event listener to listen for changed storage "onChanged"
Using native localStorage (old reply from 2011)
Content scripts run in the context of webpages, not extension pages. Therefore, if you're accessing localStorage from your contentscript, it will be the storage from that webpage, not the extension page storage.
Now, to let your content script to read your extension storage (where you set them from your options page), you need to use extension message passing.
The first thing you do is tell your content script to send a request to your extension to fetch some data, and that data can be your extension localStorage:
contentscript.js
chrome.runtime.sendMessage({method: "getStatus"}, function(response) {
console.log(response.status);
});
background.js
chrome.runtime.onMessage.addListener(function(request, sender, sendResponse) {
if (request.method == "getStatus")
sendResponse({status: localStorage['status']});
else
sendResponse({}); // snub them.
});
You can do an API around that to get generic localStorage data to your content script, or perhaps, get the whole localStorage array.
I hope that helped solve your problem.
To be fancy and generic ...
contentscript.js
chrome.runtime.sendMessage({method: "getLocalStorage", key: "status"}, function(response) {
console.log(response.data);
});
background.js
chrome.runtime.onMessage.addListener(function(request, sender, sendResponse) {
if (request.method == "getLocalStorage")
sendResponse({data: localStorage[request.key]});
else
sendResponse({}); // snub them.
});
Sometimes it may be better to use chrome.storage API. It's better then localStorage because you can:
store information from your content script without the need for
message passing between content script and extension;
store your data as JavaScript objects without serializing them to JSON (localStorage only stores strings).
Here's a simple code demonstrating the use of chrome.storage. Content script gets the url of visited page and timestamp and stores it, popup.js gets it from storage area.
content_script.js
(function () {
var visited = window.location.href;
var time = +new Date();
chrome.storage.sync.set({'visitedPages':{pageUrl:visited,time:time}}, function () {
console.log("Just visited",visited)
});
})();
popup.js
(function () {
chrome.storage.onChanged.addListener(function (changes,areaName) {
console.log("New item in storage",changes.visitedPages.newValue);
})
})();
"Changes" here is an object that contains old and new value for a given key. "AreaName" argument refers to name of storage area, either 'local', 'sync' or 'managed'.
Remember to declare storage permission in manifest.json.
manifest.json
...
"permissions": [
"storage"
],
...
Another option would be to use the chromestorage API. This allows storage of user data with optional syncing across sessions.
One downside is that it is asynchronous.
https://developer.chrome.com/extensions/storage.html
[For manifest v3]
You can execute a script that returns localstorage items from the webpage. This script can be executed from popup or background service worker.
Add this line in manifest.json:
"permissions": ["scripting"]
let [tab] = await chrome.tabs.query({ active: true, currentWindow: true })
// Execute script in the current tab
const fromPageLocalStore = await chrome.scripting.executeScript({
target: { tabId: tabId },
func: () => {
return JSON.stringify(localStorage)
}
})
const localStorageItems = JSON.parse(fromPageLocalStore[0].result)

passing info to chrome extension from website

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.

How to access localStorage in extension background page?

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.

Communication between specific web page and chrome extension

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"});
};
})

Chrome Extension API: chrome.tabs.captureVisibleTab on Background Page to Content Script

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);
});

Categories

Resources