I try to create a WebExtension which do some things if it's on a specific site in a specific folder. I tried to recognice the site and the subfolder like this:
var on = true;
//This function checks if the current site is Google after something was searched
function check_if_engine() {
var loc = window.location.href;
if (loc.includes("google")) {
alert("Includes google");
if (log.includes("search?")) {
return true;
}
return false;
}
return false;
//...
function start_all() {
if (on) {
alert("Addon activated!");
if (check_if_engine()) {
alert("Website is Google");
//...
}
//Checks if the tab loaded a new URL
browser.tabs.onUpdated.addListener(start_all);
mainfest.json:
{
"manifest_version": 2,
"name": "Is this a Google Search?",
"version": "1.0",
"description": "This Addon tells you if you are on Google Search Page",
"icons": {
"48": "icon/icon.png"
},
"browser_action": {
"default_icon": "icon/icon.png",
"default_title": "Is this a Google search?"
},
"permissions": [
"activeTab"
],
"background": {
"scripts": ["main.js"]
}
}
There aren't any other background/content scripts.
But if I tried it, there was no message, which said that "Includes google" and the returned value was "false" even if I loaded the Google Page (Instant Search disabled) and searched for something. May you can help me.
Thanks
If you use document.URL instead of location.href it should work
if(window.document.URL == "http://example.org"){
// code
}
The web you want to compare (http://example.org) always includes the protocol.
You can see the reference in the Mozilla Docs: https://developer.mozilla.org/es/docs/Web/API/Document/URL or in W3Schools: https://www.w3schools.com/jsref/prop_doc_url.asp
I used a content script which is activated at the domains specified in the manifest.json. It sends a dummy message to the background script via browser.runtime. Then it sends a message to the user
Related
I want to write a chrome extension which records the current active tab URL every time a new site is loaded and send it to a server for further use. So far I have managed to write the following code:
manifest.json
{
"manifest_version": 2,
"name": "Currenturl",
"description": "Fetches current tab url.",
"version": "0.1",
"author": "Tarun Khare",
"browser_action": {
"default_icon": "icon.png",
"default_title": "Just observing your current url."
},
"permissions": ["tabs", "activeTab"],
"background": {
"scripts": ["content.js"],
"persistent": false
}
}
content.js
chrome.tabs.query({'active': true, 'lastFocusedWindow': true}, function (tabs) {
var url = tabs[0].url;
console.log("hello: "+url);
});
I am using background scripts since chrome.tabs doesn't work in content scripts. But this extension is not printing anything in chrome console. What is the issue?
Rename content.js to background.js since this is a background script
Use chrome.tabs.onUpdated listener
Look at the correct console: Where to read console messages from background.js?
chrome.tabs.onUpdated.addListener((tabId, change, tab) => {
if (change.url) {
console.log(change.url);
}
});
It'll report the URL changes in all tabs.
You can also limit the processing to only the active tab by adding a check for tab.active property.
i try to write code based on the information you provide.
const tabUpdatelistenerFun = (tabid, changeInfo, tab) => {
const url = changeInfo.url;
if (!url || ['chrome://', 'about://'].some(p => url.startsWith(p))) return false;
const { index, active, highlighted, windowId } = tab;
if (!active) return false;
chrome.tabs.query({ index, highlighted, windowId, lastFocusedWindow: true }, () => {
console.log(url);
})
}
chrome.tabs.onUpdated.addListener(tabUpdatelistenerFun);
i think this is what you want.
You can count and extract the URL with full detail in background.js
here is the main code from below GihHub repository:
chrome.windows.getAll({ populate: true }, function (windows) {
windows.forEach(function (window) {
window.tabs.forEach(function (tab) {
//i++
collect all of the urls here, I will just log them instead
console.log("tab.ur[![enter image description here][1]][1]l aaaaakahari 2");
console.log(tab.url);
});
});
});
There is a GitHub repository of chrome Extension below here, you can find in the background.js there are methods to count and extract the open URL, and there is and even section that console it imminently when the user open or close any tab.
https://github.com/Farbod29/extract-and-find-the-new-tab-frome-the-browser-with-chrome-extention
To begin, I would like to note that I am a complete extension noob, so please forgive me if this is a silly question. I have been working on this for a couple days and have found nothing on the web that helps with this particular problem.
Here is what I am trying to do:
Say that a user is browsing a site that displays part numbers and info. Each time the user clicks on something from the site, the site loads new information and the URL changes. The extension then grabs the UID (unique identifier) from the URL and searches a database for that UID. If the UID is found in the database, a message is returned to the extension. From here, I would like to write a div to the page saying "This part is already found in the database".
The problem here appears to be that the page changes, but it's not a new page... it's just new information. I can get the extension to write to the page on initial load, but when the page changes, nothing is written.
Here is the relevant code that I am using:
Manifest
{
"manifest_version": 2,
"name": "My Extension",
"version": "1.0",
"description": "An extension to write to a page",
"icons": {
"128": "icon128.png",
"48": "icon48.png",
"16": "icon16.png"
},
"browser_action": {
"default_icon": "icon16.png",
"default_popup": "popup.html"
},
"background": {
"scripts":["./js/jquery.min.js","./js/extension-check.js"]
},
"content_scripts": [{
"js": ["./js/jquery.min.js","./js/extension-content.js"],
"matches": ["https://www.example.com/*"]
}],
"permissions": [
"activeTab",
"tabs",
"http://*/*",
"https://*/*"
]
}
The popup.html does nothing but give some buttons that the user can click and go to some sites. It has no relevant code.
extension-check.js
chrome.tabs.onUpdated.addListener(function(tabId, changeInfo, tab) {
chrome.tabs.query({'active': true, 'lastFocusedWindow': true}, function (tabs) {
if (tabs === undefined || tabs[0] === undefined) return;
var url = tabs[0].url;
if (url.indexOf("example.com/specific-directory") > 0) {
var part_url = // get part of the url
var search_url = 'myexample.com/searching?' + part_url;
$.ajax({
url: search_url,
type: 'post',
dataType: 'JSON',
success: async function(data, textStatus, jqXHR)
{
if (Object.keys(data).length != 0 && data.constructor != Object) {
// Because this script is running in the
// background, I need to send the command to
// something that has permissions to write to the page
chrome.tabs.executeScript(tabId, {
file: './js/extension-content.js'
}, function() {
chrome.tabs.sendMessage(tabId, {parameter: data});
});
}
},
error: function(jqXHR, textStatus, errorThrown)
{
console.log(jqXHR);
console.log(textStatus);
console.log(errorThrown);
}
});
}
}
});
});
extension-content.js
(function() {
chrome.runtime.onMessage.addListener(function(message) {
var receivedParameter = message.parameter;
alert ("In this - " + receivedParameter);
$(".core").prepend("<div>This is a test - " + receivedParameter + "</div>");
});
})();
NOTE: If I change this page to:
$(document).ready(function() {
$(".core").prepend("<div>This is a test</div>");
});
The div IS written to the page. But, this is written to the page once and never changes or goes away. This would display incorrect information.
The ajax is working perfectly... The alert (which is only there for a test) does display and displays with the passed parameter. However, NOTHING is written to the page.
Can someone please help me? In addition, if I have something wrong in the manifest (such as permissions), I would be ecstatic for some feedback. Again, noob at this, so I may have added that I don't need, or don't have things that I do need.
Thanks in advance.
I'm building a chrome extension which communicates with a nodejs server through websockets. The point of it is to track browsing history with content. It all seems to work, but occasionally (30% of the time) the callback in a function passed to onMessage.addListener doesn't fire correctly. Let me show you the code:
background.js
var socket = io('http://localhost:3000/');
var tabLoad = function (tab) {
socket.emit('page load', tab);
};
var tabUpdate = function (tabid, changeinfo, tab) {
var url = tab.url;
if (url !== undefined && changeinfo.status == "complete") {
tab.user_agent = navigator.userAgent;
tab.description = '';
tab.content = '';
socket.emit('insert', tab);
}
};
socket.on('inserted', function(page){
socket.emit('event', 'Requesting page content\n');
//page = {tab: page, id: docs._id};
chrome.tabs.sendMessage(page.tab_id, {requested: "content", page: page}, function(data) {
socket.emit('content', data);
});
});
try {
chrome.tabs.onCreated.addListener(tabLoad);
chrome.tabs.onUpdated.addListener(tabUpdate);
} catch(e) {
alert('Error in background.js: ' + e.message);
}
content script - public.js
var messageHandler = function(request, sender, sendContent) {
if (request.requested == "content") {
var html = document.getElementsByTagName('html')[0].innerHTML;
var data = {
content: html,
page: request.page
};
sendContent(data);
return true;
}
};
chrome.extension.onMessage.addListener(messageHandler);
The problem is that sometimes data in sendContent is undefined, while sometimes it is alright. Any ideas how to debug this or what i'm doing wrong?
I've tried replacing document.getElementsByTagName('html')[0].innerHTML with a hardcoded 'test' string, but that didn't help.
Pages like youtube/wikipedia seem to never work, while facebook/google works.
Edit: The sendContent callback does fire 100% of the time it's just that the data passed to it is undefined.
Edit: Here's the manifest file
{
"manifest_version": 2,
"name": "Socket test",
"description": "sockets are cool",
"version": "1.0",
"permissions": [
"http://st-api.localhost/",
"http://localhost:3000/",
"tabs",
"background",
"history",
"idle",
"notifications"
],
"content_scripts": [{
"matches": ["*://*/"],
"js": ["public/public.js"]
//"run_at": "document_start"
}],
//"browser_action": {
// "default_icon": "logo.png",
// "default_popup": "index.html"
//},
"background": {
//"page" : "background.html",
"scripts": ["socket-io.js", "background.js"],
"persistent": true
}
}
First off, your understanding that sendContent is executed 100% of the time is wrong.
As established in the comments, the sendMessage callback also gets executed when there was an error; and this error is, in your case, "Receiving end does not exist"
The error lies in your manifest declaration of the content script. A match pattern "*://*/" will only match top-level pages on http and https URIs. I.e. http://example.com/ will match, while http://example.com/test will not.
The easiest fix is "*://*/*", but I would recommend the universal match pattern "<all_urls>".
With that fixed, there are still a couple of improvements to your code.
Replace chrome.extension.onMessage (which is deprecated) and use chrome.runtime.onMessage
Modify the sendMessage part to be more resilient, by checking for chrome.runtime.lastError. Despite the wide permission, Chrome still won't inject any content scripts into some pages (e.g. chrome:// pages, Chrome Web Store)
Make sure you use "run_at" : "document_start" in your content script, to make sure onUpdated with "complete" is not fired before your script is ready.
As you know, when send $.ajax(..) request to another domain (cross-domain), most browser throw exception like:
XMLHttpRequest cannot load http://mysite.com/test.php. Origin
http://127.0.0.1:8888 is not allowed by Access-Control-Allow-Origin.
I am creating chrome extension and it should send a request to my website. First , i expected to see above message,too. But i confused when i see it worked fine.
First, It’s seem good, it’s working and i have what i want. But it can be horrible. Every one can use such way (only a simple script) to attack my site and grab its data.
Of course, grabbing could be happen in other ways, too.
I am new in api programing and chrome extension. Do anyone may show me the way?
manifest.json
{
"manifest_version": 2,
"name": "MyTestExtension",
"description": "this extension is for test",
"version": "1.0",
"icons": {
"128": "icon.png"
},
"browser_action": {
"default_icon": "icon.png"
},
"permissions": [
"tabs" ,
"*://*/*"
],
"content_scripts": [
{
"matches": ["*://*/*"],
"js": ["jquery-1.7.2.min.js","content_script.js"],
"run_at": "document_end"
}
]
}
content_script.js
$(document).ready(function(){
$('html').mouseup(function() {
var selectedText = getSelectedText();
if(selectedText > ''){
my_syncTest(selectedText) // here : selected test send to my site
}
});
function getSelectedText() {
if (window.getSelection) {
var selection = window.getSelection().toString();
if(selection.trim() > ''){
return selection;
}
} else if (document.selection) {
var selection = document.selection.createRange().text;
if(selection.trim() > ''){
return selection;
}
}
return '';
} });
function my_syncTest(word){
var qs = 'word='+word+'&header=555&simwords=1';
$.ajax(
{
type: "POST",
url: 'http://mysite.com/test.php',
dataType: 'json',
data : qs,
success:function(res){
console.log(res.success +" - "+ res.idWord + " - " + res.header +" - " + res.meaning);
}});
}
XMLHttpRequests from your extension work because you defined these permissions in the manifest:
"permissions": [
"*://*/*"
]
When a user installs your extension, he is informed that this extension can access his data on all sites. I prefer only including the exact site you need instead of wildcards.
http://developer.chrome.com/extensions/xhr.html
This mechanism is to protect the user, not to protect your site. If you don't want everybody to use your API, use API-keys, or look into oAuth:
http://en.wikipedia.org/wiki/OAuth
If you want to learn more about cross origin requests:
http://en.wikipedia.org/wiki/Cross-origin_resource_sharing
https://developer.mozilla.org/en-US/docs/HTTP/Access_control_CORS
I want to create an extension that will automatically redirect the youtube home page button to "/feed/subscriptions/u" instead of the usually homepage.
I have only two files manifest.json and background.js
manifest contains this
{
"name": "Youtube Home Redirector",
"version": "1.0",
"description": "Redirects Youtube Home Page automatically to subscriptions",
"background": {
"scripts": ["background.js"]
},
"manifest_version": 2
}
and my background.js contains
$('a[title*="Youtube home"]').attr('href', function(i,href) {
return href.replace('/', '/feed/subscriptions/u');
});
I know this doesn't work.... I was wondering if anyone can point me in the right direction of how to do this.
Your code has few problems
a) You are in background page not in tab you are browsing
b) $.attr() is not recognized by background page.
c) You do not have permissions on tab(s) you are updating.
The following sample can achieve your functionality.
References:
a) Manifest Files and Patterns
b) tabs.query() : For fetching all tab(s) before installation
c) tabs.onUpdated.addListener : For fetching new tab(s) after installation
d) chrome.tabs.update : For changing all tab(s) URL.
Demonstration
manifest.json
Ensure all permissions are avialable for manifest
{
"name": "URL Change",
"version": "0.0.1",
"manifest_version": 2,
"description": "This demonstrates how chrome extension Changes URL",
"background":{
"scripts":["background.js"]
},
"permissions": ["tabs","http://www.youtube.com/*"]
}
background.js
This ensures all existing tabs and all newly created tab(s) after installation with http://www.youtube.com/ URL are updated to http://www.youtube.com/feed/subscriptions/u
//Take tabId as input and change its URL
var changeURL = function (tabId) {
//Update its URL
chrome.tabs.update(tabId, {
"url": "http://www.youtube.com/feed/subscriptions/u"
}, function (tab) {
//Notification for success
console.log("Tab Updated");
});
}
//Query All tabs with URL's http://www.youtube.com/ when extension is installed for first time
chrome.tabs.query({
"url": "http://www.youtube.com/"
}, function (tabs) {
//For every tab change URL by Passing Id
for (tab in tabs) {
changeURL(tabs[tab].id);
}
});
//When ever a new tab is created this changes URL
chrome.tabs.onUpdated.addListener(function (tabId, info, tab) {
//Fetch a tab where URL is http://www.youtube.com/ and is not loaded yet
if (info.status == "loading" && info.url == "http://www.youtube.com/") {
//Change URL by passing Id of tab
changeURL(tabId);
}
});
Output:
Let me know if you need more information.