I'm having trouble getting my content script to communicate with my background page. I'm running an unpacked extension. In my content script send.js I have a line
chrome.extension.sendRequest({message: "hey"}, function(response){});
and my background.html looks like:
<script>
/* the coffeescript way, but I also tried without the
* coffeescript wrappers and got the same errors. */
(function() {
var dispatchRequest;
dispatchRequest = function(request, sender, sendResponse) {
console.log("request dispatch called");
}
chrome.extension.onRequest.addListener(dispatchRequest);
}).call(this);
</script>
I keep getting a Port error: Could not establish connection error.
Just to try to find the error I changed my background.html to
<script>
console.log("Background html is running!");
</script>
I then reloaded the page and checked the Chrome console but there was no output.
Here's my (abbreviated) manifest.json:
{
"background-page": "background.html",
"content_scripts": [{
"all_frames": true ,
"css": [ "style.css" ] ,
"js": [ "send.js" ] ,
"matches": [ "http://mail.google.com/*" ,
"https://mail.google.com/*" ]
}],
"permissions": [ "tabs", "http://*/", "https://*/", "cookies" ]
}
At this point I'm at a loss to figure out how to get the background.html to run or how to get my content script to communicate with it.
Assuming it's not just a transcription error, the manifest key for the background page should be background_page, not background-page.
Related
I am new to chrome extensions and I am having trouble while writing my first extension for chrome. What I am trying to do is detect the new tab action and redirect to a pre-defined(my webpage) url.
I wrote the manifest.json and the background.html but it doesn't seem to work.
I went through the google papers on the functions and how to use them, but there must be something I've missed.
I do not understand quite a few things that I've done in here, for example the content-scripts in manifest.json.
Some help in fixing this would be appreciated.
EDIT
EDIT2
Here is the updated code
Now I don't have the background.html file.
manifest.json
{
"name": "Tabber",
"manifest_version" : 2,
"version": "1.0",
"description": "MyExtension",
"background" : {
"scripts": ["code.js"]
},
"chrome_url_overrides": {
"newtab": "code.js"
},
"permissions": [
"tabs"
]
}
code.js
<script>
chrome.browserAction.onClicked.addListener(function(tab){
var action_url = "www.xyz.com"
chrome.tabs.create({ url: action_url });
}
</script>
Now when I open a new tab, I get to see the source of the .js file displayed.
Screenshot:
Why isn't the script being executed ?
If you want to over ride a default page, you shoud use html file, not a js file.
And if you just want to over ride a page, you do not need any background page or content script.
Here is the sample code:
menifest.json:
{
"name": "Tabber",
"manifest_version" : 2,
"version": "1.0",
"description": "MyExtension",
"chrome_url_overrides": {
"newtab": "my.html"
},
"permissions": [
"tabs"
]
}
my.html:
<!DOCTYPE html>
<html>
<head>
<title>over ride page</title>
<script type="text/javascript" src="code.js">
</script>
</head>
<body>
</body>
</html>
code.js:
window.open("http://www.google.com", "_self");
Note: you can not write any js in your html file. You need to include js file in html file.
And, you even do not need any js file. just modify the my.html as this:
<head>
<meta http-equiv="refresh"content="0;URL=http://www.google.com">
</head>
With the new chrome extensions you should not put any script code in the background page.
Inline scripts and event handlers disallowed
Due to the use of Content Security Policy, you can no longer use
tags that are inline with the HTML content. These must be
moved to external JS files. In addition, inline event handlers are
also not supported. For example, suppose you had the following code in
your extension:
https://developer.chrome.com/extensions/tut_migration_to_manifest_v2.html#inline_scripts
What you should do is move your code to a js file, either set the
manifest background property to a js file or have a background page
that links to an external js file and put all you js code there...
Try using the background property: http://developer.chrome.com/extensions/background_pages.html
1)basically add to your manifest a background script (you do not need the background page for your extension right now)
background : {
"scripts": ["background.js"]
}
2) Then add a a background.js to your extension directory and put all your js code there..
Then try again, and see if the extension works :)
3) remove all html from the js file and put just you js in the background.js
chrome.browserAction.onClicked.addListener(function(tab){
var action_url = "www.xyz.com"
chrome.tabs.create({ url: action_url });
}
Add this guy to your manifest.json file.
"chrome_url_overrides": {
"newtab": "index.html"
}
with index.html being replaced with your page. This will make it so it will show index.html when you open a new tab instead of the default.
I have an extension that basically does the same thing. Here's my manifest.json that you can use as a reference.
{
"name": "appName",
"version": "0.1",
"manifest_version": 2,
"chrome_url_overrides": {
"newtab": "index.html"
},
"description": "Desc Here",
"icons": {
// "128": "icon128.png"
},
"content_scripts": [ {
"css": ["css/styles.css"],
"js": [ ],
"matches": [ "*://*/*" ],
"run_at": "document_start"
} ],
"minimum_chrome_version": "18",
"permissions": [ "http://*/*", "https://*/*", "cookies", "tabs", "notifications" ]
}
This question already has answers here:
Can you access chrome:// pages from an extension?
(3 answers)
Closed 6 years ago.
Here is my mainfest.json:
"content_scripts": [ {
"all_frames": true,
"css": [ "css/event.css" ],
"matches": [ "\u003Call_urls>" ],
"run_at": "document_start"
}
but I cannot find content script in the chrome://extensions/ page
help!!!
You can do it on your PC by enabling chrome://flags/#extensions-on-chrome-urls and adding the necessary url, chrome://extensions/, into "matches" in manifest.json but such extension won't be possible to install on a normal browser due to an invalid scheme error.
To avoid the fatal error, don't use manifest.json to inject the content script/style, do it manually in the background or popup script via chrome.tabs.insertCSS or chrome.tabs.executeScript:
chrome://flags: enable Extensions on chrome:// URLs flag
manifest.json:
"permissions": ["chrome://*/*", "tabs"],
"background": {
"scripts": ["background.js"]
},
background.js:
var chromeURLstylable;
chrome.permissions.contains({origins: ["chrome://*/*"], permissions: ["tabs"]}, function(state) {
chromeURLstylable = state;
console.log("chrome:// urls support", state);
if (chromeURLstylable) {
chrome.tabs.onUpdated.addListener(function(tabId, info, tab) {
if (info.status == "loading" && tab.url.indexOf("chrome://") == 0) {
chrome.tabs.insertCSS({
file: "style.css",
runAt: "document_start",
allFrames: true
});
}
});
}
});
Beware of possible problems submitting such extension to the Chrome Webstore.
I want to access performance.getEntries inside all iframes on a certain page (my aim is to create a deep understanding of what is going on inside banner tags). However, I cannot inject a content script inside dynamically generated iframes it seems.
Am I doing something wrong in the example below?
Or is there a possible other route of getting performance.getEntries for these dynamically generated frames?
Consider an extremely simple html like this:
<html>
<body>
<script>
var iframe = document.createElement('iframe');
var html = '<body><img src="http://dummyimage.com/100x200/333/fff&text=hey_2_1"><img src="http://dummyimage.com/100x200/555/fff&text=hey_2_2"></body>';
iframe.src = 'data:text/html;charset=utf-8,' + encodeURI(html);
document.body.appendChild(iframe);
</script>
<img src="http://dummyimage.com/100x200/333/fff&text=hey_1_1">
<img src="http://dummyimage.com/100x200/333/fff&text=hey_1_2">
</body>
</html>
And an extension like this
manifest.json
{
"manifest_version": 2,
"name": "Banner Spy 1",
"description": "Check all iframes",
"version": "1.0",
"background": {
"scripts": ["background.js"]
},
"content_scripts": [
{
"run_at": "document_end",
"all_frames" : true,
"match_about_blank": true,
"matches": ["<all_urls>"],
"js": ["content_frame.js"]
}
],
"permissions": [
"tabs",
"activeTab",
"<all_urls>"
]
}
content_frame.js
setTimeout(function(){
var pe = performance.getEntries();
console.log(pe);
}, 1000);
Running this extension will only show performance entries for the top page, not the dynamic iframe.
I am writing a Chrome Extension mainly for Pull Requests on Github Enterprise and have ran into an issue. When the page is loaded via a refresh or direct entering of the url from your browser it runs, when it is ran from clicking a link within Github it does not.
For instance if you go to this page with Pull Requests and click into one of them it will not run. But if you refresh that same page it will run.
manifest.json
{
"name": "Github Sample",
"manifest_version": 2,
"version": "0.0.1",
"description": "Sample",
"permissions": [
"tabs", "<all_urls>",
"http://github.com/*"
],
"content_scripts": [
{
"matches": [ "https://github.com/*" ],
"js": ["github.sample.js"],
"run_at": "document_end"
}
]
}
github.sample.json
// ==UserScript==
// #author Jacob Schoen
// ==/UserScript==
alert("Extension has Ran");
To make this easier I have pushed this to github.
Any ideas on how to address this?
GitHub site uses jquery-pjax library (see How to make github style page transitions by pjax).
Basically you only need to run the content script once and attach pjax event handlers inside an injected <script> element code which will be reusing a jQueryor $ variable of the site.
In those handlers you can send a message with document.dispatchEvent to your content script that will receive it in its window.addEventListener("blabla", ...)
or you can allow the access to chrome.runtime.sendMessage on the github site in manifest.json so that page-injected code will be able to send a message that can be received by the extension in chrome.runtime.onMessageExternal listener.
Alternatively you can use chrome.webNavigation.onHistoryStateUpdated in the background script but that will cause a warning during the installation that the extension can "Read your browsing history" which is a global permission unlike the content script solution.
The working example I came up with, in case it helps anyone else.
manifest.json
{
"name": "Github Sample",
"manifest_version": 2,
"version": "0.0.1",
"description": "Sample",
"permissions": [
"activeTab",
"tabs", "<all_urls>",
"http://github.com/*"
],
"content_scripts": [
{
"matches": [ "https://github.com/*" ],
"js": ["github.sample.js"],
"run_at": "document_idle"
}
],
"web_accessible_resources": ["inject.js"]
}
github.sample.js
// ==UserScript==
// #author Jacob Schoen
// ==/UserScript==
function myAlert() {
alert("Extension has Ran");
}
window.addEventListener("pageLoadTransition", myAlert);
var s = document.createElement('script');
// TODO: add "script.js" to web_accessible_resources in manifest.json
s.src = chrome.extension.getURL('inject.js');
s.onload = function() {
this.parentNode.removeChild(this);
};
(document.head||document.documentElement).appendChild(s);
//still have to load this one for direct page loads
myAlert();
inject.js
$(document).on('pjax:success', function() {
var evt=document.createEvent("CustomEvent");
evt.initCustomEvent("pageLoadTransition", true, true, null);
document.dispatchEvent(evt);
})
I also updated the Github repository with the working example.
When I'm running the Chromium browser using:
chromium-browser --load-extension=/path/to/my/extension
--user-data-dir=/path/to/chrome/profile --app=http://localhost/somepage
some content scripts are not injected into the page. These scripts are defined as follows in the manifest file:
"content_scripts" : [{
"matches" : [ "http://*/*", "https://*/*" ],
"js" : [ "content/s1.js", "content/s2.js", "content/s3.js", "content/s4.js" ],
"run_at" : "document_end"
}]
When inspecting the page, I see that only s1.js and s4.js were injected successfully. After reloading the page all scripts are injected correctly, and my extension works as expected.
What can be the reason for that, and how to debug this?
Edit:
Those content scripts (that fail to inject sometimes) reference 'document' at the beginning. It seems like if I wrap them into something like:
setTimeout(function() { document. ... }, 5000);
They are always injected as expected. Is it possible that the document is not available, even though "run_at": "document_end" was specified in manifest?
Thanks!
You can better do this:
Create 1 content.js script:
/* inject script */
try {
var script1 = document.createElement("script");script1.type = "text/javascript";script1.src = chrome.extension.getURL("/js/injected1.js");document.getElementsByTagName("head")[0].appendChild(script1);
var script2 = document.createElement("script");script2.type = "text/javascript";script2.src = chrome.extension.getURL("/js/injected2.js");document.getElementsByTagName("head")[0].appendChild(script2);
var script3 = document.createElement("script");script3.type = "text/javascript";script3.src = chrome.extension.getURL("/js/injected3.js");document.getElementsByTagName("head")[0].appendChild(script3);
var script4 = document.createElement("script");script4.type = "text/javascript";script4.src = chrome.extension.getURL("/js/injected4.js");document.getElementsByTagName("head")[0].appendChild(script4);
} catch(e) {}
in the manifest.json:
"content_scripts" : [{
"matches" : [ "http://*/*", "https://*/*" ],
"js" : [ "content.js" ],
"run_at" : "document_end"
}]