This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Port error while changing chrome extension from manifest v1 to v2
I am trying to develop an addon for a website of mine. My users will need to be able to right-click any hyperlink on any webpage and then click a link in the Chrome context menu that will take them to my website to perform an action.
My addon is done, but everytime I try to test it, the link does not appear in the Chrome context menu when a hyperlink is reght-clicked.
Here is my files:
manifest.jason
{
"manifest_version": 2,
"background_page": "background.html",
"description": "Decrypt Short URLs.",
"icons": {
"128": "icon-128.png",
"16": "icon-16.png",
"48": "icon-48.png"
},
"minimum_chrome_version": "8.0.0.0",
"name": "xxxx.xxx",
"permissions": [ "http://*/*", "https://*/*", "tabs", "contextMenus" ],
"version": "1.0"
}
background.html
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<script>
function handleClick() {
return function(info, tab) {
var url = 'http://xxx.xxx/api.php?url=' + info.linkUrl + '&source=chromeextension'
// Create a new tab to the results page
chrome.tabs.create({ url: url, selected:true });
};
};
chrome.contextMenus.create({
"title" : "Decrypt this Link",
"type" : "normal",
"contexts" : ["link"],
"onclick" : handleClick()
});
</script>
</body>
I will appreciate any help.
I guess the problem is in your manifest file. You use manifest version 2, but your background page is declared as in manifest version 1.
You should try to change this part of manifest.json:
"background_page": "background.html",
on this one:
"background": {
"scripts": ["background.js"]
},
and put all of your background code to background.js
More info you can read here: background_pages
P.S. Sorry, Mr. Rob W already points on this problem in the comments to main question.
Related
This question already has answers here:
How to access the webpage DOM/HTML from an extension popup or background script?
(2 answers)
Closed 7 years ago.
For some reason, jQuery doesn't work in my background.js in my Google Chrome extension.
Suppose my plugin tells me all the images on the page. I verified that it gets to the below method OK, but it stops at the jQuery loop.
First, manifest.json: note I'm including jQuery, the file exists:
{
"name": "Gallery",
"version": "0.0.1",
"manifest_version": 2,
"description": "Gallery",
"browser_action": {
"default_icon": "G.png"
},
"background": {
"persistent": true,
"scripts": ["jquery-1.11.2.min.js", "background.js"]
},
"permissions": [
"tabs", "contextMenus", "http://*/*", "https://*/*"
],
"content_scripts": [
{
"matches": [
"http://*/*",
"https://*/*"
],
"css": ["contentstyle.css"],
"js": ["jquery-1.11.2.min.js", "contentscript.js"]
}
],
"icons": {
"32": "G.png"
}
}
background.js uses the jQuery syntax:
chrome.browserAction.onClicked.addListener(scanImages);
function scanImages()
{
// IT GETS HERE - THIS IS OK
alert('Clicked plugin button, about to start looping thru IMG...');
// BUT STOPS HERE: JQUERY DOESN'T EXECUTE
$("img").each(function() {
alert($(this).prop("src"));
});
// ANOTHER JQUERY THAT DOESN'T WORK
alert('Page title = ' + $(document).find("title").text());
}
To access the DOM of any page you need to use content scripts as explained in the comments. Though there is another way of accessing more than one scripts in your background.js.
Add the jquery-1.11.2.min.js in your background.html file.
....
<script type="text/javascript" src="jquery-1.11.2.min.js"></script>
<script type="text/javascript" src="background.js"></script>
....
manifest.json -->
"background": {
"page": "path/to/background.html",
"persistent": true
}
You don't have to define the scripts key also, just define your background.html page and the scripts you want in the head section of the html file. I Hope it helps.
I'm trying to make a Chrome extension which runs a script whenever the user opens a new tab.
I have the following basic code which is supposed to just paint the page red whenever the extension button is clicked.
It seems to work fine when I navigate to an actual website (ex: here on stackoverflow.com, click my extension icon, page becomes red). However, if I just create a brand new tab and click the button, the popup loads but the page never changes color.
manifest.json:
{
"manifest_version": 2,
"name": "ConsoleTap",
"version": "0.1.0",
"browser_action": {
"default_icon": "icon.png",
"default_popup": "menu.html"
},
"permissions": [
"tabs",
"<all_urls>",
"https://ajax.googleapis.com/"
]
}
menu.html:
<!doctype html>
<html>
<head>
<script src="menu.js"></script>
</head>
<body>
hello
</body>
</html>
menu.js:
document.addEventListener('DOMContentLoaded', function() {
chrome.tabs.executeScript(null,{code:"document.body.style.backgroundColor='red'"});
});
Any ideas on why the page won't update the background color on a new tab? I'm guessing the DOMContentLoaded is never fired or it's listening after the load occurs somehow?
Chrome doesn't allow content scripts on its internal pages: more info
In Chrome 60 and older it was still possible to inject content scripts into the child frames of the default new tab page because it consists of several frames so the restriction only applies to the top level frame. For the default newtab (not some newtab extension) we can match its frame url (https://www.google.com/_/chrome/newtab*) to inject a content script which will activate once a message from the popup is received:
manifest.json:
{
"name": "executeScript",
"version": "1.0",
"content_scripts": [{
"matches": ["https://www.google.com/_/chrome/newtab*"],
"js": ["newtabcontent.js"],
"run_at": "document_start"
}],
"browser_action": {
"default_icon": "icon.png",
"default_popup": "popup.html"
},
"permissions": [
"activeTab"
],
"manifest_version": 2
}
newtabcontent.js:
chrome.runtime.onMessage.addListener(function(msg) {
if (msg == "activate") {
document.body.style.background = 'red';
document.body.style.backgroundColor = 'red';
}
});
popup.js:
chrome.tabs.query({active: true, currentWindow: true}, function(tabs) {
if (tabs[0].url == "chrome://newtab/") {
chrome.tabs.sendMessage(tabs[0].id, "activate");
} else {
chrome.tabs.executeScript({
code: "document.body.style.backgroundColor='red'",
allFrames: true
});
}
});
Notes:
When this extension is installed and its permissions are displayed the user will see that it can "Read and change your data on www.google.com".
chrome.tabs.executeScript can't be used on newtab page because it instantly fails for the main frame due to unsupported scheme chrome:// and doesn't even proceed to execute on child frames.
So I'm in the midst of creating my first Chrome Extension (Trying)
I feel like I'm close... But I genuinely don't know what to google to get the answers I need. So I'm sorry if this is a silly question.
Essentially what I'm trying to do is on click of extension - Append HTML & CSS to body and run a jQuery function. But from the looks of it, I need to call in jQuery in the manifest? Which I think I've done and it's still not working.
My Code:
manifest.json
{
"name": "Title",
"description": "Description",
"version": "1.0",
"browser_action": {
"default_title": "Hover Title",
"default_icon": "icon.png"
},
"content_scripts": [ {
"js": [ "jquery-1.7.2.min.js", "background.js" ],
"matches": [ "http://*/*", "https://*/*"]
}],
"manifest_version": 2
}
background.js
chrome.browserAction.onClicked.addListener(function(tab) {
(function ($) {
$('body').append("Hello");
alert("Hello");
console.log("Hello");
}(jQuery));
});
Any insight into where I'm going wrong would be massively helpful!
Thank you!!
Chrome extension architecture is simple but it doesn't mean one can write code without studying it.
There are two methods of injecting content scripts:
Unconditionally on all specified urls, in which case "content_script" key is used in the manifest and the content scripts communicate with the background page via runtime.sendMessage.
Only when some event occurs like e.g. the user clicks our toolbar icon, in which case we only need the permission to access the active tab.
So in the given case we'll attach the icon click handler and inject the code afterwards:
manifest.json:
{
"name": "Title",
"description": "Description",
"version": "1.0",
"browser_action": {
"default_title": "Icon Title",
"default_icon": "icon.png"
},
"background": {
"scripts": ["background.js"]
},
"permissions": ["activeTab"],
"manifest_version": 2
}
background.js (this is an event page because we didn't use "persistent": true in the manifest, so be advised that the [global] variables will be lost after a few seconds of inactivity; instead you should use chrome.storage API or HTML5 localStorage/sessionStorage/and so on):
chrome.browserAction.onClicked.addListener(function(tab) {
chrome.tabs.executeScript({file: "jquery-1.7.2.min.js"}, function(result) {
chrome.tabs.executeScript({file: "content.js"}, function(result) {
});
});
});
content.js (the code runs in a sandbox so there's no need to hide global variables using IIFE)
$('body').append("Hello");
alert("Hello");
console.log("Hello");
I want to make a simple extension, which is passing a variable from background to popup. The problem is, I get 'undefined' response.
Manifest:
{
"name": "Get var",
"description": "get var",
"version": "2.0",
"permissions": [
"activeTab"
],
"background": {
"scripts": ["background.js"],
"persistent": true
},
"browser_action": {
"default_title": "Get that variable",
"default_popup": "popup.html"
},
"manifest_version": 2
}
background.js
var myURL = 'aaa';
popup.html
<!doctype html>
<html>
<head>
<script src="popup.js"></script>
</head>
<body>
</body>
</html>
popup.js
document.addEventListener('DOMContentLoaded', function () {
var bg = chrome.extension.getBackgroundPage();
var myURL = bg.myURL;
alert(myURL)
});
Your code (exactly as you posted it in your question) is correct and should work fine. (In fact when I created a sample extension using the code you provided, it did work as expected.)
You either accidentaly changed something when copying-pasting the actual code or there is something else messing things up (something you left out of your post).
BTW, I would suggest looking into event-pages (i.e. non-persistent background-pages) which are more resource-friendly. Keep in mind, that moving to an event-page would require some changes in order for the code to work:
document.addEventListener('DOMContentLoaded', function () {
chrome.runtime.getBackgroundPage(function (bg) {
var myUrl = bg.myUrl;
alert(myUrl);
});
});
Note: I do not in any way imply that the reason you receive undefined is that you use a persistent background-page. The code you posted should work fine with a persistent background-page - it is just better practice to use an event page (whenever possible).
I ran across a similar issue; my problem was that I didn't reload the extension after changing the manifest.
I would guess that the OP's issue was the same.
Finally I found the problem, I read background pages need background permission to work (chrome extension permissions documentation here). So I changed manifest like this:
{
"name": "Get var",
"description": "get var",
"version": "2.0",
"permissions": [
"activeTab,background"
],
"background": {
"scripts": ["background.js"],
"persistent": true
},
"browser_action": {
"default_title": "Get that variable",
"default_popup": "popup.html"
},
"manifest_version": 2
}
I am using the following code to access the background page function in google chrome
popup.html
function sendRequest(ea,eb)
{
console.log("Inside");
chrome.extension.sendRequest({ea:ea,eb:eb},
function(response)
{
alert(response.farewell);
});
}
background.html
<html>
<body>
<script>
chrome.extension.onRequest.addListener(
function(request, sender, sendResponse) {
sendResponse({farewell: "goodbye"});
})
</html>
</body>
</script>
manifest.json
{
"name": "My First Extension",
"version": "1.0",
"manifest_version": 2,
"background": {
"page": "background.html"
},
"content_scripts": [
{
"matches": ["http://*/"],
"js": ["popup.js"]
}
],
"description": "The first extension that I made.",
"browser_action": {
"default_icon": "icon.png",
"default_popup": "mine.html"
},
"permissions": [
"tabs","http://*/","background"
],
"web_accessible_resources": ["loading.html","bu.png"]
}
However it does not print the alert. Can anyone tell me what i am doing wrong here?
Your HTML for background.html is extremely malformed and should be fixed;
<html>
<body>
<script>
chrome.extension.onRequest.addListener(
function(request, sender, sendResponse) {
sendResponse({farewell: "goodbye"});
})
</script>
</body>
</html>
Tags should be closed in the reverse order of them being open to maintain a correct hierarchy. Since you had not done so, the <script> element was malformed and contained invalid syntax </html></body> so would not be executed correctly.
Since you're using version 2 of the manifest you may want to consider abstracting the contents of this script element (ignoring all HTML) to its own file (e.g. background.js) and change your manifest to the following;
{
"name": "My First Extension",
"version": "1.0",
"manifest_version": 2,
"minimum_chrome_version": "18",
"background": {
"scripts": ["background.js"]
},
"content_scripts": [
{
"matches": ["http://*/"],
"js": ["popup.js"]
}
],
"description": "The first extension that I made.",
"browser_action": {
"default_icon": "icon.png",
"default_popup": "mine.html"
},
"permissions": [
"tabs","http://*/","background"
],
"web_accessible_resources": ["loading.html","bu.png"]
}
Notice that the background property now contains an array of strings representing JavaScript files to be loaded (in the order specified) in to a dynamically generated background page.
I've also set the minimum_chrome_version property to 18 as manifest version 2 should only be used when targeting this version of Chrome and above.
Developers should now only really need to use background pages instead of scripts when they need to support older versions of Chrome.
Edit
It just clicked that you're attempting to execute embedded JavaScript within your background page. Manifest version 2 introduces Content Security Policies which prohibit the execution of inline (e.g. onclick="showDialog();" and href="javascript:void(0);") and embedded JavaScript. This is why your background.html won't work and why background.js will. You will also want to ensure your popup.html doesn't contain any embedded JavaScript. The best workaround (and generally best practice anyway) is to abstract all JavaScript into its own file (e.g. popup.js) which is referenced by the HTML file. For example;
<script src="/popup.js"></script>