I am developing a browser extension for Chrome and Firefox, and a few websites seem to somehow be able to prevent chrome.tabs.executeScript() from working properly. Based on my research, this doesn't seem possible, but maybe someone can indicate a trick certain websites can use?
I have developed a simplistic example that reproduces the error.
manifest.json
{
"manifest_version": 2,
"name": "Test",
"version": "0.0.0",
"author": "Test",
"description": "",
"permissions": [
"cookies",
"history",
"storage",
"tabs",
"webNavigation",
"webRequest",
"webRequestBlocking",
"<all_urls>"
],
"browser_action": {
"default_title": "Test"
},
"background": {
"persistent": true,
"scripts": ["background.js"]
}
}
background.js
window.chrome = (function() {
return window.msBrowser || window.browser || window.chrome;
})();
function doAlert() {
chrome.tabs.create({
url: 'https://twitter.com',
active: true
}, (tab) => {
chrome.tabs.executeScript(tab.id, {
code: 'alert("test")'
});
});
}
chrome.browserAction.onClicked.addListener((tab) => {
doAlert();
});
In general, I expect that a tab will open and load twitter.com, then show the alert.
In Chrome, as soon as the tab loads, I get the error "the tab was closed" as it tries to run executeScript.
In Firefox, it looks like the alert might happen before the website loads, but it happens so fast I can't really tell. There's no error logged to the background script console.
Most other URLs work just fine, popping up the alert as expected (I've confirmed it working on this site, Google, Facebook, etc). LinkedIn is another example where it doesn't work.
Related
I am making chrome extension. This is a program that checks whether a particular site is right by comparing the URL when you access Google.
The thing I want to do is compare URLs and send an alert when I connect.
However, it does not take effect until you click the chrome extension program. Please let me know the event you need.
main.js
chrome.tabs.executeScript({
code: 'document.URL;'
}, function (domain) {
var google = 'https://www.google.co.kr/';
if(domain == google){
alert('is google')
}
else
alert('not google')
})
manifest.json
{
"manifest_version": 2,
"name": "site detect",
"description": "site",
"version": "1.0",
"browser_action": {
"default_icon": "icon.png",
"default_popup": "popup.html"
},
"permissions": [
"tabs"
]
}
I'm looking to create a "new tab" extension like Panda or the Product Hunt Extension: the user can open a new tab with my website inside, with an hidden url.
I've generated my package with the awesome Extensionizr and here is my manifest.json :
manifest.json
{
"name": "My app",
"version": "0.0.1",
"manifest_version": 2,
"description": "My awesome app",
"homepage_url": "http://myapp.com",
"icons": {
"16": "icons/icon16.png",
"48": "icons/icon48.png",
"128": "icons/icon128.png"
},
"default_locale": "en",
"background": {
"scripts": [
"src/bg/background.js"
],
"persistent": false
},
"permissions": [
"tabs",
"http://myapp.com/*"
]
}
My background.js come from this answer, the problem seems really similar.
background.js
chrome.browserAction.onClicked.addListener(function(activeTab) {
var newURL = "http://myapp.com";
chrome.tabs.create({ url: newURL });
});
I'm still getting this error when I try to run the background page from the extension settings : Uncaught TypeError: Cannot read property 'onClicked' of undefined
And when I open a new tab, Google Chrome took the advantage and display me a google search page.
I do it wrong, and I don't know how/where/why
You're completely off-track. You don't want to open a (simple) new tab, you want to replace the "New Tab page".
Daniel's answer correctly explains why your code does not work, but it won't do what you wanted.
To replace Chrome's New Tab page, you need to use Override Pages:
"chrome_url_overrides" : {
"newtab": "myPage.html"
},
Inside that myPage.html, you can add an <iframe> for your remote content.
That's because you need to register the browser action in the manifest. Here is your manifest with the browser action added at the bottom.
{
"name": "My app",
"version": "0.0.1",
"manifest_version": 2,
"description": "My awesome app",
"homepage_url": "http://myapp.com",
"icons": {
"16": "icons/icon16.png",
"48": "icons/icon48.png",
"128": "icons/icon128.png"
},
"default_locale": "en",
"background": {
"scripts": [
"src/bg/background.js"
],
"persistent": false
},
"permissions": [
"tabs",
"http://myapp.com/*"
],
"browser_action": {}
}
Here are the browser action docs: https://developer.chrome.com/extensions/browserAction
So, I've looked into every other Stack Overflow post on this topic, changed everything I could line by line, and nothing is working. (Nevermind that 99% of this code is straight off dev.google.com) No matter what I try, I get the error mentioned in the title. There doesn't seem to be an explanation, so I'm hoping this group can spot the potentially stupid thing I'm missing. Thanks!
Manifest.json
{
"manifest_version": 2,
"name": "Topic Fetch",
"description": "This extension extracts the meta keywords from a news article and give you related articles from Google News",
"version": "1.0",
"browser_action": {
"default_icon": "icon.png",
"default_title" : "Get Related Links"
},
"background": {
"persistent": false,
"scripts": ["background.js"]
},
"content_scripts": [
{
"matches": ["*://*/*"],
"js": ["Content-Script.js"],
"run_at": "document_end"
}
],
"permissions": [
"tabs","<all_urls>",
"activeTab"
]
}
background.js
chrome.tabs.query({active: true, currentWindow: true}, function(tabs) {
console.log(tabs);
chrome.tabs.sendMessage(tabs[0].id, "message", function(response) {
alert(response);
});
});
Content-Script.js
chrome.runtime.onMessage.addListener(
function(message, sender, sendResponse) {
sendResponse('Hello!');
});
EDIT: Here's the code I'm using (for the most part) and info about message passing in Chrome extensions: https://developer.chrome.com/extensions/messaging.html
Content script code won't run until you refresh the page, so it isn't listening yet. The code in the background.js is not intended to be run immediately (as you have it). It should only be run after you have confirmed that the tab is listening.
I suggest trying the opposite way first: listen with the background.js and send a message with the content script.
Basically I'm trying to do a little chrome extension following Google documentation. I'd like to inject a script every time the extension button is clicked.
This is my manifest so far:
{
"name": "Example",
"manifest_version": 2,
"version": "1.0",
"permissions": [
"tabs"
],
"description": "My Chrome extension.",
"browser_action": {
"default_icon": "icon.png"
},
"background": {
"scripts": ["background.js"]
}
}
And this is my background.js:
chrome.browserAction.onClicked.addListener(function(tab) {
chrome.tabs.executeScript(tab.id, {code: "content_script.js"});
});
The problem is that the content_script is not fired, even trying with such a simple alert("aaa");
Can you please tell me what I'm doing wrong? I can't figure it out.
In order to execute a content script on a page, you must request the correct host permissions in your manifest file.
Since you want to insert a content script on click of a browser action button, it suffices to request the activeTab permission. Furthermore, you can drop the tabs permission, to reduce the number of permission warnings to zero!
{
"name": "Example",
"manifest_version": 2,
"version": "1.0",
"permissions": [
"activeTab"
],
"browser_action": {
"default_icon": "icon.png"
},
"background": {
"scripts": ["background.js"]
}
}
(The activeTab permission has been introduced in Chrome 26. If you need to support Chrome 25 and earlier, add the *://*/* or <all_urls> permissions to the manifest file).
Note: If you add a callback to chrome.tabs.executeScript, you would have received a useful error message in chrome.runtime.lastError.message:
Cannot access contents of url "http....." Extension manifest must request permission to access this host.
chrome.browserAction.onClicked.addListener(function(tab) {
chrome.tabs.executeScript(tab.id, {
file: "content_script.js"
}, function() {
if (chrome.runtime.lastError) {
console.error(chrome.runtime.lastError.message);
}
});
});
In addition to Rob's fix you should be using {file: "content_script.js"}
I'm trying to write a chrome extension and cannot seem to understand how to implement the following scenario:
user is on page X
user clicks on the extension's button
something happens (specifically, user is redirected to some url)
here's the manifest.json:
{
"name": "My First Extension",
"version": "1.0",
"description": "The first extension that I made.",
"browser_action": {
"default_icon": "icon.png",
"default_title": "my title"
},
"content_scripts": [
{
"matches": ["http://*/*", "https://*/*"],
"js": ["myscript.js"]
}
],
"permissions": [
"tabs", "https://*/*"
]
}
and here's myscript.js:
alert('entered myscript.js..');
function doMagic()
{
alert('extension button clicked!!');
}
chrome.extension.onClicked.addListener(doMagic);
i know im missing something really obvious, but cant seem to figure it out from the docs, other sites, etc.!!
Don't use a content_script, you really only need those if have to have access to the HTML of the tab.
Use a background_page for the onClicked listener and chrome.tabs.update to redirect the page.
function doMagic(tab) {
chrome.tabs.update(tab.id, { url: 'http://www.google.com' });
}
chrome.browserAction.onClicked.addListener(doMagic);