Axios is not defined in background.js (manifest v3) - google-chrome-extension

I am currently working on a chrome Extension.
My desired workflow : content-script.js sends a message to background.js. Once the message is received by background using eventListener, background starts executing a process which includes an axios.post request as well as localStorage.setItem. Since I have migrated the project's manifest to V3, background.js becomes a service worker. Hence while executing the extension, the background.js console says that "axios is not defined" as well as "localStorage is not defined".
Hence I need a way to use this in background.js (manifest v3).
Note : I also tried using chrome.storage.local, but the set function's callback is getting called, but the get function doesn't get any value.

Do not forget to place the "storage" permission in the manifest file.
manifest.json (v3)
{
"name": "Test extenstion",
"description": "Test Extension!",
"version": "1.0",
"manifest_version": 3,
"background": {
"service_worker": "background.js"
},
"action": {},
"permissions": ["storage", "activeTab", "scripting"]
}
Background.js
chrome.storage.sync.set({key: value}, function() {
console.log('Value is set to ' + value);
});
chrome.storage.sync.get(['key'], function(result) {
console.log('Value currently is ' + result.key);
});
Source:
https://developer.chrome.com/docs/extensions/reference/storage/#usage

Related

How to use signalr in chrome extensions

I'm trying to use signalr in my chrome extensions but I keep getting
'Uncaught TypeError: Cannot read property 'client' of undefined'
Now I know I need to use a script
<script src="http://localhost:3600/signalr/hubs"></script>
like this, but i can't figure out where and how to use it in chrome extensions.
My manifest file looks like this
"manifest_version": 2,
"name": "Jquery Tests",
"description": "This extension tests jquery.",
"version": "1.0",
"background": {
"scripts": ["jquery-1.9.1.min.js", "jquery.signalR-2.2.1.min.js", "background.js"],
"persistent": true
},
"content_scripts":
[
{
"matches": ["http://*/*", "https://*/*"],
"js": ["jquery-1.9.1.min.js", "jquery.signalR-2.2.1.min.js", "popup.js"]
}
],
"permissions": [
"notifications",
"background",
"tabs", "http://*/*"
],
"browser_action": {
"default_icon": "img/icon.png",
"default_popup": "popup.html"
}
and here is my popup.js where I get the error
$(document).ready(function () {
debugger;
console.log('jquery working in content!');
$.connection.hub.url = "http://localhost:3360/signalr";
$.connection.logging = true;
var ticker = $.connection.notificationHub;
//var ticker = $.connection.tempratureMonitorHub;
//signalr method for push server message to client
ticker.client.notify = function (message) {
console.log("Notification added!");
if (message && message.toLowerCase() == "added") {
updateNotificationCount();
}
}
});
[][1]
In chrome extensions , the dynamically created proxy i.e hubs file is unavailable as files are loaded once per installation.
This file contains information of client and server. To include this information in your extension you need to follow the following steps as mentioned in this link
Install the Microsoft.AspNet.SignalR.Utils NuGet package.
Open a command prompt and browse to the tools folder that contains
the SignalR.exe file. The tools folder is at the following location:
[your solution
folder]\packages\Microsoft.AspNet.SignalR.Utils.2.1.0\tools
Enter the following command:
signalr ghp /path:[path to the .dll that contains your Hub class]
The path to your .dll is typically the bin folder in your project
folder.
This command creates a file named server.js in the same folder as
signalr.exe.
Put the server.js file in an appropriate folder in your project,
rename it as appropriate for your application, and add a reference
to it in place of the "signalr/hubs" reference.

Chrome extension open new tab on new tab

I have created a Chrome extension that, as part of it's operation, opens a new tab with a specified url.
chrome.runtime.onMessage.addListener(
function(request, sender, sendResponse) {
if( request.message === "open_new_tab" ) {
chrome.tabs.create({"url": request.url});
}
}
);
(Full code available on GitHub)
This works fine on tabs with webpages, but I cannot get it to work on empty tabs, for example: chrome://apps/ To clarify, if I have a tab open and it is on stackoverflow.com, then when I click on my extension button it opens a new tab loading a generated url. When I am on a new tab, or a tab where the url begins with chrome:// then the extension does not work.
What permissions do I need to include to allow the extension to open in ANY tab? Including new tabs and any chrome:// tab?
Manifest.json:
{
"manifest_version": 2,
"name": "MyMiniCity Checker",
"short_name": "MyMiniCity Checker",
"description": "Checks what your city needs most and redirects the browser accordingly.",
"version": "0.2",
"author":"Richard Parnaby-King",
"homepage_url": "https://github.com/richard-parnaby-king/MyMiniCity-Checker/",
"icons": {
"128": "icon-big.png"
},
"options_page": "options/options.html",
"browser_action": {
"default_icon": "icon.png"
},
"permissions": ["tabs","storage","http://*.myminicity.com/","http://*/*", "https://*/*"],
"background": {
"scripts": ["background.js"],
"persistent": false
},
"content_scripts": [ {
"matches": [ "http://*/*", "https://*/*"],
"js": [ "jquery-1.11.3.min.js" ]
}]
}
Background.js:
//When user clicks on button, run script
chrome.browserAction.onClicked.addListener(function(tab) {
chrome.tabs.executeScript(null, { file: "jquery-1.11.3.min.js" }, function() {
chrome.tabs.executeScript(null, { file: "contentscript.js" });
});
});
chrome.runtime.onMessage.addListener(
function(request, sender, sendResponse) {
if( request.message === "open_new_tab" ) {
chrome.tabs.create({"url": request.url});
}
}
);
It appears as though the background.js file is not being executed. I suspect this to be a permissions. What permissions do I need in order to run this extension in every tab?
Well, this message is supposed to come from a content script you're trying to inject into the current tab.
The widest permission you can request is "<all_urls>", however, there are still URLs that are excluded from access.
You can only normally access http:, https:, file: and ftp: schemes.
file: scheme requires the user to manually approve the access in chrome://extensions/:
Chrome Web Store URLs are specifically blacklisted from access for security reasons. There is no override.
chrome:// URLs (also called WebUI) are excluded for security reasons. There is a manual override in the flags: chrome://flags/#extensions-on-chrome-urls, but you can never expect it to be there.
There is an exception to the above, chrome://favicon/ URLs are accessible if you declare the exact permission.
All in all, even with the widest permissions you cannot be sure you have access. Check for chrome.runtime.lastError in the callback of executeScript and fail gracefully.
As I was wanting this to run on EVERY page it meant I could not have the code in the content script. I moved all the code into the background script:
chrome.browserAction.onClicked.addListener(function(tab) {
//...
chrome.tabs.create({"url": newTabUrl});
//...
});
So when I click on my button the above code is called, using the enclosed jquery script.

Script doesn't fully execute in Chrome Extension

Hopefully this is something simple. I'm testing a simple Chrome Extension script and it appears it'll execute part of the script, but won't complete it. For example, if I add an alert() to the beginning of a script, it will execute the alert. But if I place it after anything calling the chrome DOM object, it won't execute. Here's an example:
Will execute alert
alert("Test");
chrome.webRequest.onCompleted.addListener(function (request) { });
Will not execute alert
chrome.webRequest.onCompleted.addListener(function (request) { });
alert("Test");
Am I missing something?
Here is my manifest:
{
"background": {
"persistent": true,
"scripts": [
"scripts/libs/jquery.1.11.2.min.js",
"scripts/background.js"
]
},
"browser_action": {
"default_icon": "resources/icon.19.png"
},
"icons": {
"48": "resources/icon.48.png"
},
"manifest_version": 2,
"name": "Test",
"permissions": [
"<all_urls>",
"webNavigation",
"webRequest",
"webRequestBlocking"
],
"version": "1.0"
}
You are missing debugging it yourself.
Go to chrome://extensions/ and load the Dev Tools for your background page. You will see an uncaught exception that stops execution.
For webRequest events, you must include a filter argument to the addListener function.

Simple Chrome Content Script Not Running

I wrote a short content script, which stops a particular site from creating new windows for link clicks.
This is my first Chrome extension, and I've scored this website and the internet for a reason why it won't run, but I can't find any. I'm probably making a fundamental amateur mistake somewhere.
Manifest.json:
{
"manifest_version": 2,
"name": "DHS Links",
"description": "Stops the school's site from constantly opening new windows.",
"version": "1.0",
"browser_action": {
"default_icon": "icon.png"
},
"content_scripts":[
{
"matches": ["*://www.darienps.org/dhs/*"],
"js": ["jquery.js", "makeNormalLinks.js"],
"run_at": "document_end"
}
]
}
I tested the Javascript file by itself on a local version of the site, so I'm pretty sure it's fine, but just in case:
makeNormalLinks.js:
$(document).ready(function() {
$("a").each(function(){
$(this).removeAttr("onclick");
});
});
A copy of jQuery is in the same directory and doesn't seem to have any issues.
Here's the onclick code for many links on the website:
onclick="window.open(this.href,'targetWindow','toolbar=no,location=no,status=no,menubar=no,scrollbars=yes,resizable=yes,')
Thank you for looking this over!
Edit:
I tried two of the injection methods from Rob W's response to another question linked to in the comments by Teepeemm.
Here's the new code for Method 1:
Manifest.json:
{
"manifest_version": 2,
"name": "DHS Links",
"description": "Stops the school's site from constantly opening new windows.",
"version": "1.0",
"browser_action": {
"default_icon": "icon.png"
},
"content_scripts":[
{
"matches": ["*://www.darienps.org/dhs/*"],
"js": ["jquery.js", "scriptLauncher.js"]
}
],
"web_accessible_resources": ["makeNormalLinks.js"]
}
scriptLauncher.js:
var s = document.createElement('script');
// TODO: add "script.js" to web_accessible_resources in manifest.json
s.src = chrome.extension.getURL('makeNormalLinks.js');
s.onload = function() {
this.parentNode.removeChild(this);
};
(document.head||document.documentElement).appendChild(s);
Method 2a:
(Uses old Manifest.js)
makeNormalLinks.js:
var actualCode = ['$(document).ready(function(){',
'$("a").each(function(){',
'$(this).removeAttr("onclick");',
'});',
'});'].join('\n');
var script = document.createElement('script');
script.textContent = actualCode;
(document.head||document.documentElement).appendChild(script);
script.parentNode.removeChild(script);
Unfortunately, neither method seems to work. I'm extremely grateful to those who commented and think we're getting close to an answer.
Solution:
Manifest.json:
{
"manifest_version": 2,
"name": "DHS Links",
"description": "Stops the school's site from constantly opening new windows.",
"version": "1.0",
"browser_action": {
"default_icon": "icon.png"
},
"content_scripts":[
{
"matches": ["*://www.darienps.org/dhs/*"],
"js": ["makeNormalLinks.js"]
}
]
}
makeNormalLinks.js:
document.addEventListener("click", function(e) {
e.stopPropagation();
}, true);
Thanks you, Scott and all who commented!
Using the onclick attribute has many weird side effects. A more up to date approach would be to add a listener to the document that filters unwanted events. Like:
document.addEventListener("click", function(e) {
e.stopPropagation();
}, true);
The true argument is important (see event capture). This will block all click event listeners from firing, but the default click action will still be triggered.
I was having a similiar issue getting the content script to fire in Google Mail. I stumbled upon a page that recommended using the "hashchange" event.
// Event listener
window.addEventListener("hashchange", function () {
alert("hashchanged");
}, false);

Chrome plugin not initializing properly

I am trying to write a chrome plugin,which I defined with the following manifest:
{
"name": "test",
"version": "1.0",
"background": { "scripts": ["background.js"] },
"permissions": [
"tabs", "http://*/*"
],
"browser_action": {
"name": "test",
"icons": ["icon.png"]
},
"manifest_version": 2
}
my background.js file looks like this:
chrome.app.runtime.onLaunched.addListener(function() {
console.log('details', chrome.app.getDetails());
});
When it loads, I see this error on the console:
Uncaught TypeError: Cannot read property 'onLaunched' of undefined
I can't figure out why I am not seeing a properly initialized chrome.app.runtime.
How do I debug this?
Gene
UPDATE:
When I run the following code:
console.log("before connection");
chrome.extension.onConnect.addListener(function(port) {
console.log("connected");
});
I see the first log output (before connection) but not the second; does this mean that it fails to connect to the browser?
chrome.app is undefined because you aren't defining your extension as an app.
Chrome extension can be only one of these in the manifest file:
browser_action, page_action, theme, or app.
In your manifest you're defining an browser action.
So take a deep breath and read the documentation for the manifest file.

Resources