chrome.tabs.sendMessage : Error handling response - google-chrome-extension

Im trying to send message to content.js from background.js when extension icon is clicked.
Background.js :
chrome.browserAction.onClicked.addListener(function(){
chrome.tabs.query({active : true, lastFocusedWindow : true}, function (tabs) {
var CurrTab = tabs[0];
chrome.tabs.sendMessage(CurrTab, 'run');
})
})
Content.js :
chrome.runtime.onMessage.addListener(function(){
view();
})
I have this error in background.js, i don't know why.
Error handling response: TypeError: Error in invocation of
tabs.sendMessage(integer tabId, any message, optional object options,
optional function responseCallback): No matching signature.
What im doing wrong?

In Background.js change the following :
chrome.tabs.sendMessage(CurrTab, 'run');
to
chrome.tabs.sendMessage(CurrTab.id, 'run');
As told by wOxxOm in the comments.
Secondly make sure that in manifest.json file you have specified the url of the website(where content script needs to be injected) in content_scripts/matches tag.

Related

How to make chrome extension 'optional permissions' dialog pop up locally?

I'm trying to get this
optional permission dialog to pop up locally while testing
I've been following this official tutorial:
https://developer.chrome.com/docs/extensions/reference/permissions/
In my case, the optional permission dialog should ideally activate when the button of class '.cbtn' is clicked on my website.
Here is chrome.permission.request part of my background.js file
document.addEventListener("DOMContentLoaded", function(event) {
document.querySelector('.cbtn').addEventListener('click', function(event) {
console.log('now activating prompt!!');
chrome.permissions.request({
permissions: ["bookmarks"]
}, function(granted){
// The callback argument will be true if the user granted the permissions.
if (granted) {
// doSomething();
console.log('Access granted');
} else {
// doSomethingElse();
console.log('Access denied');
}
});
});
});
Note: My manifest.json doesn't contain permission for bookmarks.
In the chrome://extensions/?errors for my unpacked extension, i see an error message-
"Uncaught TypeError: Cannot read property 'addEventListener' of null"
I don't know if that is because it's trying to find .cbtn on the chrome://extensions/ page itself instead of on my particular website where a button with class .cbtn actually exists,
Will appreciate any help, pointers on this

how to use NodeJS pop up a alert window in browser

I'm totally new to Javascript and I'm wondering how to use node js to pop up a alert window in browser, after sever(Nodejs) received post message from front end?
Do I need to use Ajax?
"after sever(Nodejs) received post message from front end?" show a pop up in the browser. This can not be done. I assume you want to show a popup in if the post request is success. Because you mention about Ajax, This is how it is done.
in your post router definition in the server do it as follows
router.post('/path', function(req, res){
//do something
res.jsonp({success : true})
});
something like this. finally you want to send something form the server to the client. after in the client side javascript file send the post request as follows.
$.ajax({
url:"/url/is/here",
method: "POST",
data : {
data : "what you want to send",
put : "them here"
},
cache : false,
success : function (data) {
// data is the object that you send form the server by
// res.jsonp();
// here data = {success : true}
// validate it
if(data['success']){
alert("message you want to show");
}
},
error : function () {
// some error handling part
alert("Oops! Something went wrong.");
}
});
There is a npm module for popups known as popups. You have to install it using the command npm install popups. Then use it in the following way:
var popup = require('popups');
popup.alert({
content: 'Hello!'
});
You can find more information here
First install the alert module: npm install alert
let alert = require('alert');
alert("message")
This works but there's a catch
it sends alert box like an application does
not like javascript's alert function (that sends you in browser alert popup)

Chrome extension: message from popup.js to content.js

In my Chrome extension, I am trying to send a message from popup.js to content.js. This needs to happen based on an event in the popup, so it can't be triggered on a message from content or background.
I am using the following code just to test whether the message is being passed.
In popup.js:
chrome.tabs.query({active: true, currentWindow: true}, function(tabs) {
chrome.tabs.sendMessage(tabs[0].id, {greeting: "hello"}, function(response) {
alert(response.farewell);
});
});
In content.js:
chrome.runtime.onMessage.addListener(
function(request, sender, sendResponse) {
alert(sender.tab ?
"from a content script:" + sender.tab.url :
"from the extension");
if (request.greeting == "hello")
sendResponse({farewell: "goodbye"});
});
;
The problem is that the message is only being delivered (alerted) when I open a new tab, not when I am in an active tab.
The idea is that the user is able to choose a setting in the popup which then causes the content.js to send through different data. So I should be able to send the message whenever the uses click a specific button.
Could someone please help because in every other question about this I just see the link to the Google page about Message Passing. This code is straight from there.

message passing happens twice if "run_at" : "document_start" is used in chrome extension

In my extension, I am passing a message from background.js to contentScript.js.
The issue is that when I use
"run_at" : "document_start"
in my manifest.json, the message from background.js to contentScript.js is called twice and sometimes even more than that.
Message passing more than once is a bit expensive in my case as I'm sending a call to server and the processing the same values at the server multiple times is expensive.
background.js
chrome.tabs.onUpdated.addListener(function(tabId, changeInfo, tab) {
chrome.tabs.sendMessage(tab.id, {type: "get-url", url: tab.url});
});
contentScript.js
chrome.runtime.onMessage.addListener(
function(message, sender, sendResponse) {
switch(message.type) {
case "get-url" : someFunction(message.url);
break;
// other cases
}
});
Is there a way to solve this?
chrome.tabs.onUpdated is called multiple times in the tab-update cycle (e.g. when the tab starts loading the new page, when the tab completes loading the new page, when the favicon is fetched etc).
The best option is to checj for when the tab has completed loading:
chrome.tabs.onUpdated.addListener(function (tabId, info, tab) {
if (info.status === 'complete') {
/* Now it is safe to send the message */
chrome.tabs.sendMessage(tabId, {
type: 'get-url',
url: tab.url
});
}
});
BTW, when injecting programmatically (not in manifest.json), the property's name is runAt, not run_at (docs).

Message isn't passed between background.html and popup.html

I'm trying to pass data that is saved in sessionStorage from background.html to popup.html
background.html:
chrome.extension.onRequest.addListener(function(request, sender, sendResponse) {
data = sessionStorage.getItem(request.tabId);
alert(data);
sendResponse({ data: data });
});
and in popup.html:
chrome.tabs.getSelected(null, function(tab) {
chrome.extension.sendRequest({ tabId: tab.id }, function(response) {
alert(response.data);
});
});
The popup is opened by a pageAction button, when I click the button I get an alert box with "null" on the popup and then an alert box with the data that I stored in sessionStorage on the background!
Any ideas how to fix this?
You don't need to use message/request APIs. I think this response may help you.
You also don't need sessionStorage, just store your data in a global variable of the background page. It will persist until the browser is closed or until the extension is restarted.
So, here is how I would rewrite your code:
background.html:
var data = {}; // Object storing data indexed by tab id
and in popup.html:
chrome.tabs.getSelected(null, function(tab) {
alert(chrome.extension.getBackgroundPage().data[tab.id]);
});
Note that chrome.tabs.getSelected is deprecated since Chrome 16, so popup code should be:
chrome.windows.getCurrent(function(win) {
chrome.tabs.query({'windowId': win.id, 'active': true}, function(tabArray) {
alert(chrome.extension.getBackgroundPage().data[tabArray[0].id]);
});
});
Well, I've done something dumb.
I inspected the background page by opening chrome-extension://[extension-id]/background.html in a tab instead of clicking on "inspect active views: background.html" in the extensions management page. This caused the tab to catch the request and call sendResponse, but the popup expected the REAL background page to call sendResponse (and if I understand Google's documentation regarding message passing, the fact that sendResponse was called twice is root of the problem, because the first call clears the request object)

Resources