Not able to access storage in Content Scripts in Chrome Extension Manifest V3 - google-chrome-extension

I tried to access information stored in chrome.storage.session in my content script, but the browser keeps informing me that "Access to storage is not allowed from this context" even though I enabled "storage" in manifest.json
After fetching some data in my background script, I store the received
chrome.storage.session.set({"data": data});
However, when I try to access it in my content script by running the following line:
chrome.storage.session.get(["data"],function(data){console.log(data)})
I got the following error:
Uncaught TypeError: Cannot read properties of undefined (reading 'session')
However, when I run the exact same command in my background script, I was able to retrieve the data.
I also made sure I enabled "storage" permission in my manifest.json. Why is this happening?
Thanks so much in advance!

Access to storage is not allowed from this context
As the documentation says session is only for trusted contexts by default.
To enable it in the content scripts call setAccessLevel from such a trusted context i.e. in the background script or in an extension page like the action popup or options.
chrome.storage.session.setAccessLevel({ accessLevel: 'TRUSTED_AND_UNTRUSTED_CONTEXTS' });
Cannot read properties of undefined (reading 'session')
This error says that the parent of session is undefined i.e. chrome.storage is undefined, which can only happen in these cases:
you didn't reload the extension after editing manifest.json
an orphaned content script tried to access storage after you reloaded or updated the extension
your code is not a content script, but just a page script e.g. you ran it in a script element or injected with world: 'MAIN'.

Related

Chrome extension not recognizing identity

I am trying to get use chrome.identity.getProfileUserInfo https://developer.chrome.com/apps/identity#method-getProfileUserInfo
I found my key using Chrome Extension Source Viewer and added it to my manifest.json file and under permissions added identity
"permissions": ["activeTab", "storage", "identity", "identity.email"],
But I am getting a Cannot read property 'getProfileUserInfo' of undefined when I try to run the method.
I printed out chrome and go this
It seems that chrome picked up "storage"but not "identity"
Any ideas why?
The identity permission adds chrome.identity to your background script, but not your content script. You don't say where you printed chrome from, but if it was from your content script, I would expect to see storage, but not identity.
Once you get that working, the identity.email permission may populate the user's email address, but I found that it only works if the user is logged in and has Chrome Sync switched on.

How to get a variable which can be viewed from console

I'm coding an extension which downloads a file, before downloading the file, I need to get a token which is already generated from the website on loading.
This token can be viewed from the console by typing >GetPublicTokenResult
How can I read this variable into my content script?
I've tried the following:
chrome.storage.local.get(["GetPublicTokenResult"], function(items){ items = [ { "yourBody": "myBody" } ]
console.log(items);
});
but it seems that this variable is not stored in Storage, but it can be viewed in Memory snap
Content scripts run in an isolated environment from the page. They can only interact with the DOM, javascript code can't be accesed. You need to inject your code directly in the page. Check out Insert code into the page context using a content script for a detailed tutorial.

Chrome extension background script "Cannot access contens of URL devtools..." error?

I have a background script called events.js
I am occassionally getting this error
Unchecked runtime.lastError: Cannot access contents of url
"devtools://devtools/bundled/devtools_app.html?remoteBase=https://chrome-devtools-frontend.appspot.com/serve_file/#ed9d447d30203dc5069e540f05079e493fc1c132/&dockSide=undocked".
Extension manifest must request permission to access this host.
It is apparently being generated not by events.js but by "_generated_background_page.html" but appearing in my background console log.
I suspect it is being caused by my call in events.js to:
chrome.webNavigation.onHistoryStateUpdated.addListener(function(e) {
// do stuff
}
It is driving me nuts. Can anyone please tell me what is going on?
Similar issue happened to me today. One of those facepalm moments. I discovered as i had a breakpoint in my background script to check something before the content-script was executed in the handle message, that this background devtools tab became the active tab and tired to inject the script and not the intended tab from which I activated my extension.
Hence the error.
Cannot access contents of url
"devtools://devtools/bundled/devtools_app.html?remoteBase=https://chrome-devtools-frontend.appspot.com/serve_file/#7345a6d1bfcaff81162a957e9b7d52649fe2ac38/&dockSide=undocked".

How to programmatically enable flash in Chrome? [duplicate]

chrome.tabs returns undefined despite the fact I set tabs in the permissions block.
"permissions": [
"tabs",
"http://*/*",
"https://*/*"
],
"content_scripts": [
{
"matches": [
"http://*/*",
"https://*/*"
],
"js": [
"js/myScript.js"
],
"all_frames": true
}
],
But in myScript.js the following returns undefined.
chrome.tabs
As content script has its own limitations,
chrome.tabs is only available in background scripts and popup scripts.
If you wanna to use chrome.tabs then pass message from content_script to background script and play with chrome.tabs.
Content scripts have only limited access to Chrome APIs. This access does not include the API you are trying to use (e.g. chrome.tabs). If you need to use that API, you will have to do so in a background script1.
As listed in Chrome's content scripts documentation, the APIs available to a content script are [I have placed deprecated methods in strikethrough format]:
extension ( getURL , inIncognitoContext , lastError , onRequest , sendRequest )
i18n
runtime ( connect , getManifest , getURL , id , onConnect , onMessage , sendMessage )
storage
A couple of the listed APIs are deprecated and have been for some time. Those that are deprecated have moved to different locations (also listed above):
extension.onRequest ➞ runtime.onMessage
extension.sendRequest ➞ runtime.sendMessage
While not officially deprecated, extension.lastError is also available as runtime.lastError. At this point, it is usually referred to at that location:
extension.lastError ➞ runtime.lastError
Partition your extension into background scripts and content scripts
You are going to need to separate your code into what needs to be in a background script and what needs to be in content scripts, based on the capabilities available to each type of script. Content scripts have access to the DOM of the web page into which they are injected, but limited access to extension APIs. Background scripts have full access to the extension APIs, but no access to web page content. You should read the Chrome extension overview, and the pages linked from there, to get a feel for what functionality should be located in which type of script.
It is common to need to communicate between your content scripts and background scripts. To do so you can use message passing. This allows you to communicate information between the two scripts to accomplish things which are not possible using only one type of script.
For instance, in your content script, you may need information which is only available from one of the other Chrome APIs, or you need something to happen which can most appropriately (or only) be done through one of the other Chrome extension APIs. In these cases, you will need to send a message to your background script, using chrome.runtime.sendMessage(), to tell it what needs to be done, while providing enough informaiton for it to be able to do so. Your background script can then return the desired information, if any, to your content script. Alternately, you will have times when the processing will primarily be done in the background script. The background script may inject a content script, or just message an already injected script, to obtain information from a page, or make changes to the web page.
Background script means any script that is in the background context. In addition to actual background scripts, this includes popups and options pages, etc. However, the only page that you can be sure to have consistently available to receive messages from a content script are your actual background scripts defined in manifest.json. Other pages may be available at some times as a result of the user's interaction with the browser, but they are not available consistently.
This answer was moved from a duplicate question, and then modified.
https://developer.chrome.com/extensions/tabs#method-getSelected shows
getSelected
chrome.tabs.getSelected(integer windowId, function
callback)
Deprecated since Chrome 33. Please use tabs.query {active: true}.
Gets the tab that is selected in the specified window.
Maybe, you should use chrome.tabs.query in popup.js like this
chrome.tabs.query({active: true, currentWindow: true}, function(tabs){
console.log(tabs[0].url);
});
, reload your extension and check the result in the inspect element of your extension.
result image
code image
https://developer.chrome.com/extensions/tabs#type-Tab shows that
The URL the tab is displaying. This property is only present if the extension's manifest includes the "tabs" permission.(Just for remind someone forgot. I was forgot it when I just test it.)
Check this answer also https://stackoverflow.com/a/6718277/449345
This one worked for me
chrome.tabs.getSelected(null, function(tab){
console.log(tab);
});

How to inject javascript into Chrome DevTools itself

Ok, so just the other day I learned that you can inspect the devtools if it is in its own window(explained here). I also learned that you can style the devtools with your own css by editing the Custom.css file in your profile on your computer(more on that here).
What I want to do is not only add css, but also javascript, via a chrome extension. I am very aware of devtools pages, but those do not do what I want. Pretty much I want to get a content script to run on the devtools inspector itself. I found one extension that does exactly this, but for the life of me I have not been able to replicate it(even when copy-pasting the code!!). The extension is the "Discover DevTools Companion extension" from Code School(on the webstore). They even explain how it works, but I still have had no luck. That was the only extension I have found that does what I want. So I guess what I'm really asking is if its just me that cannot get it to work or if others that try are having trouble also.
Usually, you cannot create a Chrome extension which injects code in a devtools page.
The "Discover DevTools Companion" extension from now on, referred to as DDC is allowed to do this, because this extension is whitelisted in the source code of Chromium: (this is no longer the case)
// Whitelist "Discover DevTools Companion" extension from Google that
// needs the ability to script DevTools pages. Companion will assist
// online courses and will be needed while the online educational programs
// are in place.
scripting_whitelist_.push_back("angkfkebojeancgemegoedelbnjgcgme");
If you want to publish an extension in the Chrome Web Store with these capabilities, give up.
If you want to create such an extension for personal / internal use, read further.
Method 1: Impersonate the DDC a whitelisted extension
The easiest way to create an extension with such permissions is to create an extension with the extension ID of a whitelisted extension (e.g. ChromeVox). This is achieved by copying the "key" key of its manifest file to your extension's manifest (see also: How to get the key?). This is a minimal example:
manifest.json
{
// WARNING: Do NOT load this extension if you use ChromeVox!
// WARNING: Do NOT load this extension if you use ChromeVox!
// WARNING: This is a REALLY BIG HAMMER.
"content_scripts": [{
"js": [ "run_as_devtools.js" ],
"matches": [ "<all_urls>" ]
}],
// This is the key for kgejglhpjiefppelpmljglcjbhoiplfn (ChromeVox)
"key": "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDEGBi/oD7Yl/Y16w3+gee/95/EUpRZ2U6c+8orV5ei+3CRsBsoXI/DPGBauZ3rWQ47aQnfoG00sXigFdJA2NhNK9OgmRA2evnsRRbjYm2BG1twpaLsgQPPus3PyczbDCvhFu8k24wzFyEtxLrfxAGBseBPb9QrCz7B4k2QgxD/CwIDAQAB",
"manifest_version": 2,
"name": "Elevated Devtools extension",
"version": "1.0"
}
run_as_devtools.js
if (location.protocol === 'chrome-devtools:') (function() {
'use strict';
// Whatever you want to do with the devtools.
})();
Note: This method is truly a hack. Since the extension shares the same ID as ChromeVox, both extensions cannot co-exist. And if Chrome decides to remove the whitelisted extension, then your permissions will evaporate.
Instead of filtering via the content script, you can also use the include_globs key to restrict the content script to devtools only.
Method 2: Modify resources.pak
I suggest to go with method 1 if possible. When method 1 fails (e.g. because the extension is no longer whitelisted), use the next method.
Get paktools.py, unpack.py and pack.py from DennisKehrig/patch_devtools (on Github).
Locate your Chrome directory containing resources.pak.
Run python2 unpack.py resources.pak, which creates a directory resources containing all files (all file names are numbers).
Locate the file containing a script which runs in the context of the developer tools. Add your desired code there.
Remove resources.pak
Run python2 pack.py resources to create the new resources.pak file.
Note: resources.pak may be replaced when Chrome is updated, so I suggest to create a script which automates my described algorithm. That shouldn't be too difficult.
If you're interested, you can look up the .pak file format in ui/base/resource/data_pack_literal.cc (description in human language).
For those googlers who end up at this page (as I did) looking for something else, this page answers the question of manipulating DevTools ITSELF - not adding jQuery to DevTools, or injecting javaScript onto a web page. For those, see here instead:
Inject jQuery into DevTools (Chrome or Firefox):
Firefox DevTools: Automatically injecting jQuery
Inject your own javascript/css onto any web page:
How to edit a website's background colors

Resources