I'm developing Chrome Extension and I need to load a javascript file to content scripts, but that file is being served via webpack-dev-server. So it's approachable only on localhost.
I tried to change my manifest.json:
"content_scripts": [
{
"matches": [
"http://*/*",
"https://*/*"
],
"js": [
"http://localhost:3000/scripts/content_bundle.js"
],
"run_at": "document_end",
"all_frames": false
}
But then I got an error in Chrome Extensions window:
Only local files can be specified in "content_scripts" section.
Solution:
add "permissions": ["http://localhost:3000/scripts/*", "tabs"] to manifest.json
download the script using XMLHttpRequest (there are many examples) in your background script (or better an event page script) when needed
save it in chrome.storage.local or localStorage (so you can load it on every extension start from the storage without redownloading)
inject the script:
add a tabs.onUpdated listener and inject the script using tabs.executeScript
alternatively use declarativeContent API with RequestContentScript action (despite the warning on the doc page it should be actually supported in the Stable channel but of course do some tests first).
Related
I'm writing a chrome extension and I'm having trouble accessing an iframe. I ended up googling this issue and all I got was "security policy" and why the iframe can't be accessed.
In manifest.json "all_frames": true does not help:
"permissions": ["tabs","storage","<all_urls>","activeTab"],
"content_scripts": [
{
"matches": ["<all_urls>"],
"js": ["content.js", "raschet.js"],
"run_at": "document_end",
"all_frames": true
}
],
I found a way to disable web security when turning on the browser: --disable-web-security(+ other settings).
If we do this and go to the site with recaptcha https://www.google.com/recaptcha/api2/demo,
after can use the code to click on the captcha:
document.querySelectorAll("iframe")[0].contentDocument.querySelectorAll("div[class='recaptcha-checkbox-border']")[0].click()
Yes it works, but disabling security is not my option.
There are programs for automating work in the browser iMacros and Selenium IDE. These are also extensions with javascript and here they were able to realize focus and click on the iframe.
Exampele iMacros:
FRAME F=1
TAG POS=1 TYPE=DIV ATTR=CLASS:recaptcha-checkbox-border&&ROLE:presentation&&TXT:
Exampele Selenium IDE:
command: select frame target: index=0
command: click target: css=.recaptcha-checkbox-border
Is it possible to repeat the same in my extension using JS or Jquery?
I wrote a firefox addon use webextensions tech. By default firefox load the addon when the page loaded over. But some pages hava slowly loaded js,like some ads or statistics code, so the addon will not load if I stop the unnecessary page load. Or wait a long time before the addon loaded.
So can I setup the addon loaded time? (example: Before the page loaded)
Check out the run_at option in the content_scripts' manifest options. For example, you may use the following options:
content_scripts": [
{
"js": ["my-script.js"],
"matches": ["https://example.org/"],
"match_about_blank": true,
"run_at": "document_start"
}
]
I've got a Google Chrome extension which has the following content script syntax in it's manifest.json:
"content_scripts": [
{
"matches": [
"https://example.com/*"
],
"js": ["js/jquery-2.1.1.js", "js/custom.js"],
"run_at": "document_end",
"all_frames": true
}
],
When testing this extension on an Ember site, it runs on initial page load but after changing the page, it does not get injected again.
For non-Ember users, Ember can update the URL and page content without performing an entire page reload which appears to be causing this issue.
Is anyone aware of a work-around for examples like this?
This was fixed by using chrome.WebNavigation.onHistoryStateChanged which fires every time the page updates.
So I've been trying to send data from a web page to the Chrome Application (not Chrome Extension). Reading stuff around, according to me, this primarily would require the use of url_handlers for invoking Chrome App from a web page, content scripts to inject JS into the web page and/or Messaging for communication between Chrome Application and the web page.
Also, installed App from it's .crx, else loading unpacked directory leads to this error:
"content_scripts is only allowed for extensions and legacy packaged apps, but this is a packaged app."
Now, I tried injecting JS in the required site. However, on inspecting using Chrome Dev Tools, there's no such entry in the Sources->Content scripts section for that site. It simply didn't inject itself when using a Chrome App. It works perfectly with extensions but I want to use Chrome App for other functionalities.
As an alternative, I looked for Messaging examples where its usage is mentioned as:
"... your app or extension can receive and respond to messages from regular web pages."
But, somehow I couldn't get it working.
Any headers on either of the approaches? Other Suggestions?
manifest.json:
{
"name": "App",
"version": "1.0",
"manifest_version": 2,
"minimum_chrome_version": "31",
"app": {
"background": {
"scripts": ["background.js"]
}
},
"permissions": [
{"fileSystem": ["write", "retainEntries", "directory"]},
"storage",
"http://example.com/*"
],
"externally_connectable": {
"matches": ["http://example.com/*"]
},
"content_scripts": [{
"matches": ["http://example.com/*"],
"js": ["content.js"]
}]
}
Indeed, you can't have content scripts in an app.
However, using externally_connectable is valid.
You have already declared that you want to be externally connectable from example.com. (Note: be careful when defining match patterns, for instance this one does not cover www.example.com)
In example.com's own scripts, you can then include the following:
chrome.runtime.sendMessage("idOfYourAppHere", message, function(response) {
/* ... */
});
And in the app (probably its background script) you can catch that with
chrome.runtime.onMessageExternal.addListener(function(message, sender, sendResponse) {
/* ... */
sendResponse(response);
});
This does require you to know the ID in advance. You can pin it by packing your extension and extracting the "key" field from the manifest. See this question for some more details.
I'm working on a chrome extension and I need to get the event when the tab is closed so I can fire of an post to a server. This is what I have atm.
chrome.tabs.onRemoved.addListener(function (tabId) {
alert(tabId);
});
But I can't get it to work. Anyone got any ideas?
Edit:
When I'm running it, it says
Uncaught TypeError: Cannot read property 'onRemoved' of undefined
Edit2: manifest.json
{
"name": "WebHistory Extension",
"version": "1.0",
"manifest_version": 2,
"description": "storing webhistory",
"content_scripts":[
{
"matches": ["http://*/*"],
"js": ["jquery-1.7.min.js","myscript.js"],
"run_at": "document_end"
}
],
"permissions" : ["tabs"]
}
You can't use chrome.tabs API in content scripts:
However, content scripts have some limitations. They cannot: Use
chrome.* APIs (except for parts of chrome.extension)
source
What you need to do is to establish communication between content script and background page. Background page has access to chrome.tabs API:
These limitations aren't as bad as they sound. Content scripts can
indirectly use the chrome.* APIs, get access to extension data, and
request extension actions by exchanging messages with their parent
extension.
source
Everything is in the first five paragraphs of content script documentation.