I am making a chrome extension, and trying to send a message from the chrome extension page to the content.js. I know that in order to that I need to send the message to the bakcground.js and forward it to the content.js by sending it to either a specific tabs. I hvae done that many times and have not had any issues, but this time it just doesn't work.
main.js file (from the extension page):
chrome.runtime.sendMessage({
name: "stop"
})
background.js:
chrome.tabs.query({}, tabs => {
for (let i = 0; i < tabs.length; i++) {
if (tabs[i].status == "complete") {
chrome.tabs.sendMessage(tabs[i].id, { msg: "Hello" })
}
}
})
content.js:
function recieve(msg) {
console.log(msg)
}
chrome.runtime.onMessage.addListener(recieve)
manifest.json:
{
"manifest_version": 2,
"name": "app",
"description": "app description",
"version": "3.0.0",
"icons": {
"19": "./images/icon_19.png",
"128": "./images/icon_128.png",
"150": "./images/icon_150.png"
},
"browser_action": {
"default_title": "title"
},
"permissions": [
"tabs",
"alarms",
"notifications"
],
"content_scripts": [
{
"matches": [
"<all_urls>"
],
"js": [
"jquery-3.4.1.min.js",
"content.js"
]
}
],
"background": {
"scripts": [
"background.js"
]
}
}
Related
My Chrome extension mv3 receives messages from webpage and replies to it. Here are the codes in webpage to send message to extension:
chrome.runtime.sendMessage(chromeExtensionId,
{
"Message": "Hello",
"Data":
{
"Name": 'Jason'
}
},
function(response) {
console.log("chrome.runtime.sendMessage", response);
});
and codes in extension's background.js to receive message and reply with true/false:
chrome.runtime.onMessageExternal.addListener(function(message, sender, sendResponse) {
console.log(message, sender));
sendResponse(true);
});
manifest.json:
{
"background": {
"service_worker": "background.js"
},
"action": {
"default_icon": {
"16": "images/logo16.png",
"32": "images/logo32.png"
},
"default_title": "My Extension"
},
"content_scripts": [ {
"all_frames": true,
"match_about_blank": true,
"js": [ "util.js", "contentscript.js" ],
"matches": [ "http://*/*", "https://*/*" ],
"run_at": "document_end"
} ],
"description": " ",
"externally_connectable": {
"matches": [ "https://*.mysite.com/*", "http://*.mysite.com/*" ]
},
"icons": {
"128": "/images/logo128.png",
"16": "/images/logo16.png",
"32": "/images/logo32.png",
"48": "/images/logo48.png"
},
"manifest_version": 3,
"name": "My Extension",
"permissions": ["cookies", "tabs", "proxy", "alarms", "storage", "downloads", "webRequest", "notifications", "nativeMessaging", "clipboardRead", "clipboardWrite", "declarativeNetRequest","declarativeNetRequestFeedback" ],
"host_permissions": ["<all_urls>"],
"version": "4.0.7"
}
Most of the time it works fine.
The only problem is when i set my webpage as startup page of chrome, which means the page is opened immediately when chrome starts, sendMessage does not return and console.log in both sender and receiver sides are not printed. There is no error output in console either. It looks like codes freeze inside sendMessage. What's going on there?
It's a known problem. Chrome intentionally delays extensions at browser startup to show the active tab faster. The workaround is to repeat sendMessage:
send('abcdefgkhgghfg........', {foo: 'bar'}, res => {
console.log('response', res);
});
function send(extensionId, msg, callback, retry = 20) {
const timer = setTimeout(send, 100, extensionId, msg, callback, retry - 1);
chrome.runtime.sendMessage(extensionId, msg, response => {
if (!chrome.runtime.lastError || !retry) {
clearTimeout(timer);
callback(response);
}
});
}
I'm trying to get tweets on my timeline using a Chrome Extension.
I'm selecting elements using the following query -
const tweets = document.querySelectorAll("[data-testid='tweetText']");
I'm running this in the contentScript.js at 'document_idle'
I keep getting an empty NodeList.
Here is my manifest.json
{
"manifest_version": 3,
"name": "Mute",
"version": "0.1.0",
"description": "My Chrome Extension",
"icons": {
"16": "icons/icon_16.png",
"32": "icons/icon_32.png",
"48": "icons/icon_48.png",
"128": "icons/icon_128.png"
},
"background": {
"service_worker": "background.js"
},
"action": {
"default_title": "Mute"
},
"permissions": [
"activeTab",
"scripting"
],
"content_scripts": [
{
"matches": [
"https://twitter.com/home"
],
"run_at": "document_idle",
"js": [
"contentScript.js"
]
}
]
}
This is a sample MutationObserver.
manifest.json
{
"name": "MutationObserver",
"version": "1.0",
"manifest_version": 3,
"content_scripts": [
{
"matches": [
"<all_urls>"
],
"js": [
"matches.js"
]
}
]
}
matches.js
console.log("MutationObserver:Start");
const onMutation = (mutations) => {
// mo.disconnect();
for (const { addedNodes } of mutations) {
for (const node of addedNodes) {
if (node) {
if (node.dataset && node.dataset.testid) {
// console.log("node.dataset.testid=" + node.dataset.testid)
if (node.dataset.testid == "cellInnerDiv") {
const tweets = node.querySelectorAll("[data-testid='tweetText']");
console.log(tweets);
}
}
}
}
}
// observe();
}
const observe = () => {
mo.observe(document, {
subtree: true,
childList: true,
});
}
const mo = new MutationObserver(onMutation);
observe();
I am new to extensions. my extension's purpose is to save the URLs of all tabs ever opened on the browser. This is my background script so far:
var URLs = [];
chrome.history.onVisited.addListener(storeURL);
chrome.storage.onChanged.addListener(function (changes, namespace) {
for (let [URL, { oldValue, newValue }] of Object.entries(changes)) {
URLs[URLs.length] = newValue;
}
});
function storeURL(HistoryItem) {
console.log("entered in storeURL function", HistoryItem)
chrome.storage.sync.set({ URL: HistoryItem?.url }, function () {
console.log('URL is set to ' + HistoryItem?.url);
});
}
The problem is that i am able to access the current url in developer tools but its not being stored in URLs.
Note: I want the extension to be autonomous and not popup. my manifest.json:
{
"name": "URL tracker",
"version": "0.0.1",
"manifest_version": 3,
"description": "Stores the browser URLs",
"action": {
"default_popup": "url.html",
"default_icon": "logo-small.png"
},
"background": {
"service_worker": "background.js"
},
"content_scripts": [
{
"matches": ["<all_urls>"],
"css": [],
"js": ["content.js"]
}
],
"icons": {
"128": "logo-small.png",
"512": "logo-small-2.png"
},
"permissions": [
"history",
"tabs",
"activeTab",
"storage"
]
}
I have a working extension for Chrome and Firefox and I tried to make it work in Microsoft Edge as well. for some reason the content script stuck on "runtime.sendMessage" function. I have using Edge 40.15063.
the Edge console says:
"API Call: 'runtime.sendMessage'"
"script block (9) (214,17)."
manifest.json:
{
"manifest_version": 2,
"name": "injecter",
"version": "0.1.5.9",
"author": "kovler",
"description": "check the page url and then inject a code",
"icons": {
"48": "icons/icon32.png",
"96": "icons/icon96.png"
},
"applications": {
"gecko": {
"id": "test#test.com",
"strict_min_version": "45.0"
}
},
"content_scripts": [{
"matches": ["http://*/*", "https://*/*"],
"js": ["edge.js", "content.js"]
}],
"background": {
"scripts": ["edge.js", "constants.js", "promises.js", "main.js"],
"persistent": true
},
"permissions": [
"http://*/",
"https://*/",
"storage",
"webNavigation",
"tabs",
"activeTab",
"cookies",
"webRequest",
"webRequestBlocking"
],
"-ms-preload": {
"backgroundScript": "backgroundScriptsAPIBridge.js",
"contentScript": "contentScriptsAPIBridge.js"
}
}
edge.js:
if (typeof chrome == "undefined" || typeof chrome.runtime == "undefined")
chrome = browser;
content.js:
(function(){
function injectLocalScript (content, node) {
var th = document.getElementsByTagName(node)[0];
var s = document.createElement('script');
s.setAttribute('type', 'text/javascript');
s.innerHTML = content;
th.appendChild(s);
}
function getAnswer(theMessageEvent) {
if (theMessageEvent) {
if (theMessageEvent.name === "Inject") {
injectLocalScript(theMessageEvent.codeLine, 'body');
console.log("injected");
}
}
}
chrome.runtime.sendMessage({ name: "injectionCompleted" }, getAnswer );
}());
New to making extensions, I origally was attempting to load cookies but realised my EventPage.js didn't seem to be loading - since a basic console.log("Hello") wasn't loading.
I am loading the extension via Chrome "Load unpacked extensions", where manifest,content and background scripts are.
The code attached below is what I've been using to see if I can even get a console log from the event page. Only the content script loads, even If I press a key and that is logged.
CHROME:58
Any suggestions?
Manifest.SON
{
"manifest_version": 2,
"name": "Facebook Extension ",
"version": "1.0",
"description": "",
"permissions": ["storage", "webNavigation", "activeTab", "tabs", "cookies",
"*://*.facebook.com/*"],
"background": [
{
"scripts": ["event_Page.js"],
"persistent" : false
}
],
"content_scripts": [
{
"matches": ["*://*.youtube.com/*"],
"css": ["style.css"],
"js": ["jquery-2.1.0.min.js", "talkToEvent.js"]
}
]
talkToEvent.js
console.log("Hello World!s");
$(document).ready(function() {
console.log("DOM READY!");
$(document.documentElement).keydown(function (e) {
console.log("Key Has Been Pressed!");
chrome.runtime.sendMessage({Message: "getTextFile"}, function (response) {
;
})
})
});
event_Page.js
console.log("Atleast reached background.js")
chrome.runtime.onMessage.addListener (
function (request, sender, sendResponse) {
console.log("Reached Background.js");
if (request.Message == "getTextFile") {
console.log("Entered IF Block");
$.get("http://localhost:63342/Projects/StackOverflow/ChromeEXT/helloWorld1", function(response) {
console.log(response);
// to send back your response to the current tab
chrome.tabs.query({active: true, currentWindow: true}, function(tabs) {
chrome.tabs.sendMessage(tabs[0].id, {fileData: response}, function(response) {
;
});
});
})
}
else {
console.log("Did not receive the response!!!")
}
}
);
You have an incorrect manifest.json.
According event pages docs it should be an object, but in your manifest it is an array.
Correct manifest.json:
{
"manifest_version": 2,
"name": "Facebook Extension ",
"version": "1.0",
"description": "",
"permissions": [
"storage",
"webNavigation",
"activeTab",
"tabs",
"cookies",
"*://*.facebook.com/*"
],
"background": {
"scripts": [
"event_Page.js"
],
"persistent": false
},
"content_scripts": [
{
"matches": [
"*://*.youtube.com/*"
],
"css": [
"style.css"
],
"js": [
"jquery-2.1.0.min.js",
"talkToEvent.js"
]
}
]
}
Also fixed missed comma and close bracket.