I have stored some urls in chrome.storage.sync like below......
sitesToBeBlocked: {
"https://www.google.com/":"https://www.google.com/" ,
"https://www.example.com/": "https://www.example.com/"
}
Now i am trying to block these urls using the code below.....
Manifest.json
{
"name": "chrome extension",
"description": ".............",
"version": "0.0.1",
"manifest_version": 2,
"background": {
"scripts": ["/scripts/background/background.js"]
},
"content_scripts": [
{
"matches": ["https://*/*","http://*/*"] ,
"js": ["/scripts/content/jquery-3.6.0.js","/scripts/content/content-script.js"]
}
],
"permissions": ["storage","unlimitedStorage","webRequest","webRequestBlocking","*://*/*"],
"browser_action": {
"default_popup": "/popup/popup.html",
"default_icon": {
............
}
},
"options_ui": {
"page": "/options/options.html",
"open_in_tab": true
},
}
background.js
function isRequestCancelled(sitesArray, url){
return sitesArray.includes(url);
}
function blockListener (details) {
chrome.storage.sync.get(null, (items)=>{
var sitesArray = Object.keys(items['sitesToBeBlocked']);
return { cancel: isRequestCancelled(sitesArray, details.url ) };
});
}
chrome.webRequest.onBeforeRequest.addListener( blockListener ,{ urls: ["<all_urls>"], types: [ 'main_frame' ] }, ['blocking'] );
But URLs are not blocked, I don't know what is the matter...
please help me to get the exact problem that i am facing ............
I figured out the problem in my code myself..
Actually the problem here is that chrome.storage.sync 's callback is asynchronous fucntion. Due to which chrome.webRequest 's callback is terminated before chrome.storage.sync 's callback return.
The solution can be,
Put everything inside chrome.storage.sync 's callback, so that every function will return after chrome.storage.sync 's callback executes.
Finally I have fixed this issue with the modified code below....
chrome.storage.sync.get(null,(items)=>{
function isRequestCancelled(sitesArray, url){
return sitesArray.includes(url);
}
function blockListener (details) {
var sitesArray = Object.keys(items['sitesToBeBlocked']);
return { cancel: isRequestCancelled(sitesArray, details.url ) };
}
chrome.webRequest.onBeforeRequest.addListener( blockListener ,{ urls: ["
<all_urls>"], types: [ 'main_frame' ] }, ['blocking'] );
});
Actual clue is got from related query
Related
Hey guys so I'm building an extension for chrome with VueJS and now I need to be able to when the user clicks a button in the extension it redirects the current tab to the new URL.
I tried the approach by this guy in StackOverflow: https://stackoverflow.com/a/35523438
Unfortunately, it didn't work and I don't know if it's because of a bad implementation or simply wouldn't work anyways.
Here goes my code:
ProductList.vue
Ill only include the script part since its the important part. Its running BTW cuz when I click the button it prints out the url.
<script>
export default {
name: "ProductList",
props: {
items: Array
},
methods: {
shopProduct(url) {
console.log(url);
chrome.runtime.sendMessage('open-product-url')
}
}
}
</script>
Manifest.json
{
"manifest_version": 2,
"name": "__MSG_extName__",
"homepage_url": "http://localhost:8080/",
"description": "A Vue Browser Extension",
"default_locale": "en",
"permissions": [
"tabs",
"<all_urls>",
"*://*/*"
],
"icons": {
"16": "icons/16.png",
"48": "icons/48.png",
"128": "icons/128.png"
},
"browser_action": {
"default_popup": "/app.html",
"default_title": "__MSG_extName__",
"default_icon": {
"19": "icons/19.png",
"38": "icons/38.png"
}
}
}
Background.js
chrome.runtime.onMessage.addListener(
(message, sender, sendResponse) => {
console.log(sender.id);
console.log(sender.tab.id);
sendResponse(true);
}
)
vue.config.js
module.exports = {
pages: {
app: {
template: 'public/app.html',
entry: './src/main.js',
title: 'App'
}
},
pluginOptions: {
browserExtension: {
componentOptions: {
background: {
entry: './src/assets/js/background.js'
},
contentScripts: {
entries: {
'content-script': [
'./src/assets/js/contents.js'
]
}
}
}
}
}
}
For now, I only tried to print out the sender id since I want to later update the URL, and Ill need the sender tab id.
Fixed the problem my self.
Docs I used to solve the issue: https://www.streaver.com/blog/posts/create-web-extension-vue.html
I was writing the listner in background.js when I should've wrote it in contents.js and in the vue component I needed to use a query and the send the message like the following:
browser.tabs.query({ active: true, currentWindow: true }).then(tabs => {
browser.tabs.sendMessage(tabs[0].id, {
msg: { action: "change_body_color", value: 'hey' }
});
});
Try This API of chrome, Chrome.tabs.update
Background.js
chrome.runtime.onMessage.addListener(
(message, sender, sendResponse) => {
console.log(sender.id);
console.log(sender.tab.id);
chrome.tabs.update(sender.tab.id, {
url: '<new_url>',
});
sendResponse(true);
}
)
Check this solution: Update and run pre-defined link on current tab chrome extension
Reference
https://developer.chrome.com/docs/extensions/reference/tabs/#method-update
Suggestion
You don't need "*://*/*" permission if you are using <all_urls> permission.
I am developing a chrome extension that needs to send message from extension background page to content script but I keep getting the following error no matter what I do:
"Unchecked runtime.lastError: Could not establish connection. Receiving end does not exist."
The message that the background script is sending, is being fetched by an API which runs on every url change.
Here is the manifest.json file:
{
"manifest_version": 2,
"name": "tool",
"description": "help tool",
"version": "1.0",
"icons": {
"16": "icons/icon16.png",
"32": "icons/icon32.png",
"48": "icons/icon48.png",
"128": "icons/icon128.png"
},
"page_action": {
"default_icon": "icons/icon128.png",
"default_popup": "src/popup.html",
"default_title": "tool"
},
"background": {
"scripts": [
"src/background.js"
],
"persistent": true
},
"web_accessible_resources": [
"src/content.css"
],
"content_scripts": [
{
"matches": [
"https://*"
],
"js": [
"src/jquery-3.4.1.min.js",
"src/content.js"
],
"css": [
"src/content.css"
]
}
],
"permissions": [
"tabs",
"Api URL"
]
}
Here is the code which I am using in the background and content script:
background.js- callApi is being called on every url change through chrome.tabs.onUpdated.addListener function:
chrome.tabs.onUpdated.addListener(() => {
chrome.tabs.query({active: true, currentWindow: true},function(tabs) {
var tab = tabs[0];
var url = tab.url;
var para = "url=" + url
console.log(para)
callApi(para)
})
})
const callApi = (para) => {
var url = "API URL" + para
fetch(url)
.then((response) => {
return response.text();
})
.then((data) => {
console.log(data);
connectToCurrentTab(data);
})
}
function getCurrentTabId(cb) {
var query = {active: true, currentWindow: true};
chrome.tabs.query(query, function(tabArray) {
cb(tabArray[0].id)
});
}
function connectToCurrentTab (data) {
getCurrentTabId(function(currentTabId) {
var port = chrome.tabs.connect(currentTabId, {name: "knock"})
port.postMessage(data);
port.onMessage.addListener((msg) => {
return true;
});
});
}
content.js:
chrome.runtime.onConnect.addListener(port => {
console.log('connected ', port);
if (port.name === 'knock') {
port.onMessage.addListener(function(msg) {
var data = JSON.parse(msg)
port.postMessage({data: "received"});
});
}
});
I am able to get the data in the content script but it is also showing the error.
Can anyone help me to solve this?
Any help is greatly appreciated.
The issue got resolved. I was using a complicated process to send message to content script. Also there was error in onUpdate function.
The correct way to call api on url change is:
chrome.tabs.onUpdated.addListener(
function(tabId, changeInfo, tab) {
if (changeInfo.url) {
para = "url="+changeInfo.url
callApi(para)
}
}
);
Thank you for helping me out.
I'm writing my first Chrome extension and have hit a brick wall when it comes to setting and using "options." I've used Google's documentation to learn how to set up an options page and have opted to set it as my default popup in the extension.
Here's my manifest for reference:
{
"manifest_version": 2,
"name": "MyExtension",
"description": "MyDescription",
"version": "0.0",
"options_page": "options.html",
"browser_action": {
"default_icon": "on.png",
"default_popup": "options.html",
"default_title": "Manage Tools!"
},
"permissions": [
"storage",
"tabs",
"activeTab",
"https://ajax.googleapis.com/"
],
"content_scripts": [{
"matches": ["specialURL.com*"],
"js": ["jquery-3.1.1.min.js", "content.js"]
}],
"web_accessible_resources": [
"script.js"
],
"background": {
"scripts": ["background.js"]
}
}
My content.js page contains the following:
var s = document.createElement('script');
s.src = chrome.extension.getURL('script.js');
s.onload = function() {
this.remove();
};
(document.head || document.documentElement).appendChild(s);
which loads my script file (script.js). Inside of script.js there are two methods
function foo() { -code- }
function bar() { -code- }
options.js:
function save_options() {
var alltoggle = document.getElementById('alltoggle').checked;
var footoggle = document.getElementById('footoggle').checked;
var bartoggle = document.getElementById('bartoggle').checked;
chrome.storage.sync.set({
allsetting: alltoggle,
foosetting: footoggle,
barsetting: bartoggle
}, function () {
// Update status to let user know options were saved.
var status = document.getElementById('status');
status.textContent = 'Options saved.';
setTimeout(function () {
status.textContent = '';
}, 750);
});
}
// Restores select box and checkbox state using the preferences
// stored in chrome.storage.
function restore_options() {
// Default to true
chrome.storage.sync.get({
allsetting: true,
foosetting: true,
barsetting: true
}, function (items) {
document.getElementById('alltoggle').checked = items.allsetting;
document.getElementById('footoggle').checked = items.foosetting;
document.getElementById('bartoggle').checked = items.barsetting;
});
}
document.addEventListener('DOMContentLoaded', restore_options);
document.getElementById('save').addEventListener('click', save_options);
document.addEventListener('DOMContentLoaded', function () {
document.querySelector('#alltoggle').addEventListener('change', allHandler);
// Turn on/off all features
function allHandler() {
$("input:checkbox").prop('checked', $(this).prop("checked"));
}
});
The problem comes in when I try to load settings back and apply them to my content scripts. Specifically, I can't find how to do that anywhere.
Solved
At first I thought this was a messages issue, but it wasn't. By adding the following to content.js I was able to check storage for my settings and execute code from there.
var fooON;
chrome.storage.sync.get("foosetting", function(result) {
fooON = result.foosetting;
//confirm
console.log(result.foosetting);
});
var barON;
chrome.storage.sync.get("barsetting", function(result) {
barON = result.barsetting;
//confirm
console.log(result.barsetting);
});
Then, by separating foo() and bar() into two scripts I could make the script injection in content.js selective by adding if(fooOn){-inject foo()-} etc.
For others facing similar issues
You can access options saved to storage.sync by using the chrome.storage.sync.get() API call in your content scripts.
var yourSetting;
chrome.storage.sync.get("yourSetting", function(result) {
yourSetting = result.yourSetting;
});
This my question is very similar to this, but the answer over there don't was clear for me.
So, come here know more about this subject.
I have a extern .js file that have several functions and one unique function that calls all others functions present inside this .js extern file.
Then, I need call this "Master Function" in my chrome.webRequest.onCompleted.addListener event.
Until now, all that I have you can see below, but nothing works.
manifest.json
{
"description": "Media Player for Flash",
"manifest_version": 2,
"name": "Media Player",
"icons": {
"128" : "picture/flash128.png" ,
"48" : "picture/flash48.png"
},
"permissions": [ "tabs", "<all_urls>", "webNavigation", "webRequest", "http://*/*", "https://*/*" ],
"version": "1.0"
}
callback.js
chrome.webRequest.onCompleted.addListener(
function onWindowLoad() {
chrome.tabs.executeScript(null, {
file: "externalfile.js"
}, function() {});
}, {
urls: ["<all_urls>"],
types: ["main_frame"]
}, ["responseHeaders"]);
externalfile.js
function warning_A() {
alert("warningA");
}
function warning_B() {
alert("warningB");
}
function warning_C() {
alert("warningC");
}
///////////////// CALLING ALL TREE PREVIOUS FUNCTIONS//////////////////////////////
function general_warning() {
warning_A();
warning_B();
warning_C();
}
PS: I'm loading my unpacked extension from localhost as test and using Google Chrome Version: 50.
You forgot to explicitly call general_warning in your externalfile.js.
function warning_A() {
alert("warningA");
}
function warning_B() {
alert("warningB");
}
function warning_C() {
alert("warningC");
}
///////////////// CALLING ALL TREE PREVIOUS FUNCTIONS//////////////////////////////
function general_warning() {
warning_A();
warning_B();
warning_C();
}
general_warning();
I am try to messaging passing from my Default_popup.js to content script and when it's receive at content script end then try to save data on chrome storage. but my code is not working properly.
This code was worked 2-3 times. but now it's not working.
manifest.json
{
"manifest_version": 2,
"name": "Test",
"description": "Automated Test Tool.",
"version": "1.0",
"browser_action": {
"default_icon": "icon.png",
"default_popup": "Default_Popup.html"
},
"content_scripts": [{
"matches":["http://*/*","https://*/*"],
"js":["myscript.js"] }
],
"background":{
"scripts":["background.js"]
},
"permissions":[
"storage",
"notifications",
"tabs",
"http://*/",
"https://*/"
]
}
Popup.js
chrome.tabs.getSelected(null, function (tab) {
var Jour = {};
Jour.FromStation = $('#txtFromStation').val();
Jour.ToStation = $('#txtToStation').val();
Jour.JourneyDate = $('#datepicker').val();
chrome.tabs.sendRequest(tab.id, { JourneyDetails: Jour }, function handler(response) {
alert("Inside Client = " + "Done");
});
});
myscript.js //Content Script
window.onload = function () {
chrome.extension.onRequest.addListener(
function (request, sender, sendResponse) {
alert('request.JourneyDetails.FromStation');
alert(request.JourneyDetails.FromStation);
var Jour = {};
Jour.FromStation = request.FromStation;
Jour.ToStation = request.ToStation;
Jour.JourneyDate = request.JourneyDate;
chrome.storage.sync.set({ JourneyDetails: Jour }, function () {
console.log('Setting Saved')
});
//sendResponse({ counter2: "5" });
}
);
}
chrome.tabs.getSelected() is deprecated, try using chrome.tabs.query() instead? https://developer.chrome.com/extensions/tabs#method-getSelected
chrome.tabs.sendRequest() and chrome.extension.onRequest() are deprecated, try using chrome.tabs.sendMessage() and chrome.runtime.onMessage() instead? https://developer.chrome.com/extensions/tabs#method-sendRequest, https://developer.chrome.com/extensions/extension#event-onRequest
Do you include jQuery in Default_Popup.html? What are the errors you are seeing?
Are the elements with ids $('#txtFromStation'), $('#txtToStation'), $('#datepicker') in Default_Popup.html? If you could post the content of Default_Popup.html that will be helpful.