Chrome Extension, send data between tabs - javascript

I'm developing a simple extension, but I cannot figure out how to move on. I guess it's a 'simple' question.
The scenario:
The user select an text
Opens the contextual menu and hit the extension
A new tab will open
Fill a textarea w/ the selected/highlighted text
I did the first three items, and to the fourth I tried chrome.tabs.query/executeScript/messaging, ajax post… without success.
function sendReport() {
return function(info, tab) {
var selectedText = info.selectionText;
var cr_url = 'http://localhost/cr/index.php';
var tab = chrome.tabs.create({ url: cr_url }, function(tab){
});
}
}
var OgameToConverter = chrome.contextMenus.create({
"title": "Enviar Relatório",
"contexts": ["selection"],
"onclick": sendReport()
});

You can send messages between tabs by using chrome.runtime.sendMessage or chrome.tabs.sendMessage. To receiving the message, add an listener for the message on the receiving tab by using the chrome.runtime.onMessage.addListener method.
Example:
chrome.tabs.create({ url: cr_url }, function(tab){
chrome.tabs.sendMessage(tab.id, {greeting: "hello"}, function(){});
});
In the tab:
chrome.runtime.onMessage.addListener(
function(message, sender, sendResponse) {
// do what you want to the message
});
Or, you can create the window with window.open, send the message with window.postMessage and recieve the message by catching the Message event with something like window.addEventListener("message", ...);

Related

Chrome extension create tab and send msg to it

I tried different things, but it doesn't work.
In my popup.html i've created a button. When i click it, i wan't to create a new tab and send to it a message. Here is the code:
$("#openLink").click(function () {
chrome.tabs.create({url: 'http://jquery.com'}, function (tab) {
console.log(tab.id);
alert(tab.id);
chrome.tabs.sendMessage(tab.id, 'hello');
});
});
And in the content script i try to use this:
chrome.runtime.onMessage.addListener(
function (request, sender, sendResponse) {
alert('message received');
});
But it doesn't alert me nothing.
Please help.

How to run callback function from content script after loading page ? chrome extension

I want to run a callback function from content script after tab loading new page .
Here is my code :
content_script.js
chrome.runtime.onMessage.addListener(function(request, sender, callback) {
if (request.id == "content_script") {
// open google.com
chrome.runtime.sendMessage({
"id" : "openUrl",
"url" : "https://google.com"
}, function(response) {
});
// call background script
// go to the claim code page
chrome.runtime.sendMessage({
"id" : "background"
}, function() {
alert("test");
});
}
});
background.js
chrome.runtime.onMessage.addListener(function(msg, sender, sendResponse) {
if (msg.id == "openUrl") {
var tabId = sender.tab.id;
var url = msg.url;
openUrl(tabId, url);
} else if (msg.id == "background") {
setTimeout(function() {
sendResponse();
}, 5000);
}
});
function openUrl(tabId, url) {
chrome.tabs.update(tabId, {
url : url,
active : false
}, function() {
console.log("open tab url callback");
});
};
I also uploaded the source code to google drive, you can download it using the bellow link :
https://drive.google.com/open?id=15zSn40z4zYkvCZ8B-gclzixvy6b0C8Zr
as you can see the alert test don't show !
However if I remove the code which open new url , then alert ("test") appear !
I am not sure why ! but it looks like javascript lost the reference to the call back function when I open new url .
How can I solve the problem ? what's the correct way ?
Thank you
The sendResponse function becomes invalid after the message callback returns, unless you return true from the event listener to indicate you wish to send a response asynchronously. (https://developer.chrome.com/extensions/runtime#event-onMessage)
Add return true; in background.js to make this handler asynchronous.
Now you get an error Attempting to use a disconnected port object in the sendResponse(); call of background.js, and yes, that's a result of the page navigating away and losing the context that the content script was running in.
There's no way to make this work: The context in which you wanted to call alert() simply doesn't exist anymore.
Try using chrome.tabs.sendMessage instead. But this means you have to set up the listener at the top level, and not inside of any callback. Message passing is hard.

Reading DOM content from a background script?

Let's say there are two websites: x.com and y.com. Here is what I have done so far:
When a button is clicked on x.com, send a message to a background script.
The background script opens a new tab to y.com.
However, now that the tab to y.com has opened, how can I read from the DOM from y.com and use that info in the content script that is running on x.com?
Here is my code so far:
content.js (Content script that runs for x.com)
var btn = document.querySelector('my-btn')
// Send message when btn is clicked
btn.addEventListener('click', message)
function message() {
chrome.runtime.sendMessage({ message: 'Get Y data' }, null, function() {
// I want to use data from `y.com` here somehow
})
}
background.js
chrome.runtime.onMessage.addListener(function(response, sender, sendResponse) {
if (response.message !== 'Get Y data') {
return
}
var url = '...'
chrome.tabs.create({ active: true, url: url }, function (tab) {
// How do I read DOM from this new `tab` and send it back to content script?
})
})

Execute content script within new tab - chrome extentions

I'm trying to create a chrome extension that scrapes some content from a particular website and then opens a new tab and does stuff with the scraped data.
Below is a test I made to see how I might do this. Unfortunately I can't seem to execute the newtab-script.js file as I get this error:
Unchecked runtime.lastError while running tabs.executeScript: Cannot
access contents of url
"chrome-extension://FAKEIDgfdsgfdsgfdsgdsgfdsgFAKEID/newpage.html".
Extension manifest must request permission to access this host.
at Object.callback (chrome-extension://FAKEIDgfdsgfdsgfdsgdsgfdsgFAKEID/background.js:43:25)
websitescrape.js
var button = document.createElement("button");
button.classList.add("web-scrape");
button.innerHTML = "scrape web";
document.querySelector('.placeIWantToPutButton').appendChild(button);
button.addEventListener('click', scrapeData);
function scrapeData(){
//do website scraping stuff here...
var fakedata = [{test:"data1"},{test:"data2"}];
//send scraped data to background.js
chrome.runtime.sendMessage({setdata: fakedata}, function(tab){
//callback
});
}
background.js
var dataTempStorage = [];
chrome.runtime.onMessage.addListener(function (request, sender, sendResponse) {
if (request.setdata) {
dataTempStorage = request.setdata;
chrome.tabs.create({
'url': chrome.extension.getURL('newpage.html')
}, function(tab) {
chrome.tabs.executeScript(tab.id, {
file:chrome.extension.getURL("newtab-script.js")});
});
}
if (request == "getdata") {
sendResponse({data: dataTempStorage});
}
});
newtab-script.js
chrome.runtime.sendMessage("getdata", function (response) {
doStuff(response.data);
});
function doStuff(){
//Do staff on newpage.html with data scraped from original page
}
newpage.html
// page ready to be filled with awesome content!
Cause: content scripts can't be injected into extension pages with chrome-extension:// scheme.
Solution: since you have control over that html page just reference the content script file explicitly.
newpage.html:
<script src="newtab-script.js"></script>
</body>
</html>
And don't use executeScript.

chrome extension, pass data from content to background

I've created a chrome extension that consists of manifest.json, content.js and background.js. in content.js, I'm extracting the current tab's URL and in background.js, I'm opening a new tab. what I want to do, which doesn't work is to pass the URL from content and append it to the URL that I'm calling in background.
content.js:
chrome.extension.onMessage.addListener(function(request, sender, sendResponse)
{
if(request.greeting=="gimmieyodatas")
{
var output ="URL=";
//check for the character '?' for any parameters in the URL
var paramIndex = document.URL.indexOf("?");
//if found, eliminate the parameters in the URL
if (paramIndex > -1)
{
output += document.URL.substring(0, paramIndex);
};
sendResponse({data: output});
}
else{
sendResponse({});
}
});
background.js:
var output2;
chrome.tabs.getSelected(null, function(tab) {
chrome.tabs.sendMessage(tab.id, {greeting:"gimmieyodatas"}, function(response) {
output2 = response.data;
});
});
chrome.browserAction.onClicked.addListener(function() {
chrome.tabs.create({url: "http://www.google.com?" + output2}, function(tab) {
chrome.tabs.executeScript(tab.id, {file: "content.js"}, function() {
sendMessage();
});
});
});
When I run the extension from an open tab, it opens google on a new tab, but it doesn't append the current tab's URL in google URL, meaning the 'output' data does not get passed to the background.js. What am I doing wrong?
The problem is that you are not telling the background page to send a message when a new tab is opened. The call to chrome.tabs.getSelected only happens once when the extension is first run -- it does not happen every time a new tab is opened.
You're on the right track by using the background page as an intermediary between the two content pages, but I suggest a different approach:
Load the content script every time a new tab is opened, via the manifest file:
"content_scripts": [
{
"matches" : [
"<all_urls>"
],
"js" : [
"content.js"
]
}
],
Use a much simpler content script that just sends a message to the background with the current URL page as soon as it loads:
(content.js)
var paramIndex = document.URL.indexOf('?');
if (paramIndex > -1) {
chrome.runtime.sendMessage({output2: 'URL=' + document.URL.substring(0, paramIndex)});
}
When the background page receives the message it saves the URL to a global variable:
(background.js)
var output2;
chrome.extension.onMessage.addListener(function(request, sender, sendResponse) {
output2 = request.output2;
});
You can then load that URL when the action button is clicked:
(background.js)
chrome.browserAction.onClicked.addListener(function() {
chrome.tabs.create({url: "http://www.google.com?" + output2});
});

Categories