I am trying to use a Chrome extension to set a cookie when I get a Selenium Webdriver instance to open a page. I have tried following a variety of ways suggested in different Stack Overflow posts but none of them ever show when I open the page inspector.
Manifest - I made sure to list permissions to any URL:
{
"name": "Test",
"description": "Test",
"version": "2.0",
"manifest_version": 2,
"permissions": ["cookies", "<all_urls>", "background", "tabs", "webRequest", "webRequestBlocking", "http://*/*"],
"background": {
"scripts": ["background.js"],
"persistent": true
} ,
"content_scripts": [
{
"matches": ["*://*/*"],
"js": ["script.js"]
}
]
}
Background JS - I have several attempts to create a cookie and none of them are showing when I inspect the web or background page:
chrome.cookies.set({ url: "https://google.com/", name: "CookieVar0", value: "123" });
chrome.webRequest.onBeforeRequest.addListener(
function(details) {
chrome.tabs.query({active: true, currentWindow: true}, function(tabs) {
chrome.tabs.sendMessage(tabs[0].id, {test: testVar}, function(response) {
console.log("Response connected");
setCookie();
chrome.cookies.set({ url: "http://example.google.com", name: "CookieVar1", value: "123" });
});
});
},
...
function setCookie(){
console.log("Set Cookie");
chrome.cookies.set({"name":"Sample1","url":"http://developer.chrome.com/extensions/cookies.html","value":"Dummy Data"},function (cookie){
console.log(JSON.stringify(cookie));
console.log(chrome.extension.lastError);
console.log(chrome.runtime.lastError);
});
}
Content Script - I've read that you're normally not supposed to try to set cookies form the content script but some posts mentioned it so I tried it anyways:
window.addEventListener('load', loadEvent => {
console.log("Test 321");
// window.customlog = "Updated window!!!";
let window = loadEvent.currentTarget;
window.document.title='You changed me!';
chrome.cookies.set({ url: "http://example.google.com", name: "CookieVar3", value: "123" });
});
So its not a complete answer but something I realized was that no matter what URL you put in the cookie it is going to be filed under the url of the page you are running the extension. So chrome.cookies.set({ url: "https://google.com/", name: "CookieVar0", value: "123" }); was working but it wasn't under "https://google.com/" but "current page url" instead. The one setting "Sample1" was not working until I changed the format to match the one setting CookieVar0 and then it was fine.
So I still can't get it to work as desired everywhere but there is at least some progress. Hope this helps someone!
Related
I would like to send a message from popup to content script and to log an object once I get the response from this end but I'm getting the following error: Could not establish connection. Receiving end does not exist.
Why might this error be occurring and how should I fix it? Any help would be appreciated.
Besides the below code, I tried the workaround suggested on this link (https://www.youtube.com/watch?v=jooc7xMkz2E), by implementing the communication between the popup and content-script with long-lived connections and adding an event listener on load to the browser window but it did not worked either.
Implemented a similar function for sending the message to the background but without passing the tabs as an argument and it is logging the response from the background to the popup but not from content-script to popup, the error appears when I try to send a message from popup to content script and logging the respective response.
Below are the main project files.
Popup.ts:
ngOnInit(): void {
...
this.sendMessageToContentScript();
}
sendMessageToContentScript() {
chrome.tabs.query({currentWindow: true, active: true} , function (tabs){
var activeTab = tabs[0];
chrome.tabs.sendMessage(activeTab.id, { command: 'HelloFromPopup1' }, (response) => {
var parsed_res = JSON.parse(response);
console.log("content-script: " + parsed_res);
});
});
}
content_script.ts:
chrome.runtime.onMessage.addListener(
function(msg, sender, sendResponse) {
if (msg.command == "HelloFromPopup1") {
var personal_data = {
firstname: "Max",
lastname: "Hennigan",
role: "role",
location: "United Kingdom"
};
sendResponse(JSON.stringify(personal_data));
}
}
);
Manifest.json:
{
"name": "Extension name",
"version": "1.0",
"description": "Desc",
"manifest_version": 2,
"permissions": [
"activeTab",
"webNavigation",
"tabs",
"storage",
"http://*/",
"https://*/"
],
"background": {
"persistent": true,
"scripts": [
"background.js",
"runtime.js"
]
},
"browser_action": {
"default_popup": "index.html#/home",
"default_icon": "assets/icons/favicon-32x32.png",
"default_title": "title"
},
"content_scripts": [
{
"matches": [ "<all_urls>" ],
"js": [ "content_script.js" ]
}
],
"content_security_policy": "script-src 'self' 'unsafe-eval'; object-src 'self'"
}
app-routing.module.ts:
const routes: Routes = [
{path: 'home', component: HomeComponent}
];
#NgModule({
imports: [RouterModule.forRoot(routes, {useHash: true})],
exports: [RouterModule]
})
Edited:
Following the suggestion of wOxxOm on the comments, I've tried to add programmatic injection to my popup.ts but it is giving me a response of "1" from the content script, it is not logging the object as it should.
I have tried it like this:
Popup.ts (with programmatic injection):
sendMessageToContentScript() {
chrome.tabs.query({currentWindow: true, active: true} , function (tabs){
var activeTab = tabs[0];
chrome.tabs.executeScript(activeTab.id, {file: "content_script.js" }, function (response) {
if (!chrome.runtime.lastError) {
var parsed_res = JSON.parse(response[0]);
console.log("content-script: " + parsed_res);
}
});
});
}
Content-script for this programmatic injection part is equal as the content-script file of my non edited part of the question.
I am working on a chrome extension that has 2 script files. One is attached to the manifest.json as content_scripts(page script). And I also have a script file attached to my add-on popup.html file(add-on script).
When I declare a var in my page script then I try calling it in my add-on script and I get undeclared varible.
Can can I get communications between the two scripts?
Because if I try doing it all in one then it can not access the elements of the opposite page.
You can easily pass values from background to content script using messaging.
Se below a simple example:
manifest.json
{
"name": "test",
"version": "0.0.1",
"manifest_version": 2,
"description": "Test ",
"background": {
"scripts": [
"background.js"
]
},
"browser_action": {
"default_title": "Test "
},
"permissions": [
"*://*/*",
"tabs"
], "content_scripts" : [{
"matches" : ["*://*/*"],
"js" : ["content.js"]
}]
}
background.js
chrome.browserAction.onClicked.addListener(function(){
chrome.tabs.query({active: true, currentWindow: true}, function(tabs) {
chrome.tabs.sendMessage(tabs[0].id, {data: "some value"});
});
});
content.js
chrome.extension.onMessage.addListener(handleMessage);
function handleMessage(request) {
console.log(request.data);
}
I read this and searched on other places but I can't solve this issue. I am using long-lived connections. I send a message from content script to background and after that I want to send a message from background to content script. However, I am not able to receive messages on the content file for some reason...
Content script:
var port = chrome.runtime.connect({name: "my-channel"});
// receive messages
port.onMessage.addListener(function(msg) {
console.log(msg); // doesn't log anything
});
document.addEventListener('DOMContentLoaded', function () {
document.getElementById('alertButton').addEventListener('click', function() {
// send message
port.postMessage({myProperty: "value"});
});
});
Background:
chrome.runtime.onConnect.addListener(function(port) {
if(port.name == "my-channel"){
port.onMessage.addListener(function(msg) {
// do something
// then send message to the content
port.postMessage({myProperty: "value"});
});
}
});
EDIT: my manifest.json
{
"manifest_version": 2,
"name": "Test extension",
"version": "1.0",
"browser_action": {
"default_popup": "main_ui.html",
"default_title": "Test Extension"
},
"content_scripts": [{
"matches": ["<all_urls>"],
"js": ["logic.js"]
}],
"background": {
"scripts": ["background.js"],
"persistent": true
},
"permissions": [
"tabs",
"activeTab"
]
}
solution: I was using an old reference of "port" of when connection happened. The 2nd argument of the listener (that isn't visible there) is actually the port.
I've been testing this for a few good hours, I've also taken a, known to work at the time, example. See here:
https://stackoverflow.com/a/27829709/2430488
Its just not working for me or I'm not sure how to test. I'm opening the developer tools, and also the extension developer tools, but nothing is being logged in either window.
The code I'm using:
manifest.json
{
"manifest_version": 2,
"name": "Some test",
"description": "https://stackoverflow.com/questions/27823740",
"version": "0",
"background": {
"scripts": [
"background.js"
]
},
"permissions": ["tabs", "<all_urls>"],
"content_scripts": [
{
"matches": ["<all_urls>"],
"js": ["cont.js"]
}
]
}
cont.js
chrome.runtime.onMessage.addListener(function(msg, sender, sendResponse) {
if (msg.message && (msg.message == "DIMENSION")) {
var dimension = getPageDiemension(document.documentElement);
console.log('Dimension:', dimension);
sendResponse(dimension);
}
return true;
});
getPageDiemension = function(currentDom){
return {
x: 0,
y: 0,
w: currentDom.scrollWidth,
h: currentDom.scrollHeight
}
}
background.js
getPageDimension = function (){
chrome.tabs.query({active: true, highlighted: true}, function(tabs) {
chrome.tabs.sendMessage(tabs[0].id, { message: "DIMENSION" }, function(response){
if (response !== null) console.log('Response:', response);
else console.log('Response is null');
});
});
};
Please help, I really am not sure what I'm doing wrong, I've been looking at the documentation for the last few hours but I can't understand why is not working.
Thank you.
As rsanchez mentions, your background defines a function getPageDimension.
It is then never called, so your extension does exactly nothing. There doesn't seem to be any error, you just never do anything.
You need to bind a call to getPageDimension to some event, e.g. clicking a Browser Action.
Hey trying to redirect from page1 to page2 (within tab, not open new ones) at a specific time.
manifest.json:
{
"name": "Google",
"description": "Test",
"version": "1.0",
"manifest_version": 2,
"background": {"scripts":["script.js"]},
"permissions": [
"alarms",
"webRequest",
"*://www.google.com/*",
"webRequestBlocking"
]
}
script.js:
var host = "https://www.facebook.com/"
chrome.alarms.onAlarm.addListener(function(alarm){
return {redirectUrl: host}
})
chrome.webRequest.onBeforeRequest.addListener(
function(details) {
return chrome.alarms.create("redirect", {when: Date.now() + 5000})
},{
urls: [
"*://www.google.com/*"
],
types: ["main_frame", "sub_frame", "stylesheet", "script", "image", "object", "xmlhttprequest", "other"]
["blocking"]
)
code to redirect was taken from This Question,
code to use timer was taken from This Question
EDIT: Solution thanks to Xan's answer below
manifest.json
{
"name": "Google",
"description": "Test",
"version": "1.0",
"manifest_version": 2,
"content_scripts": [{
"matches": ["*://www.google.com/*"],
"js": ["script.js"]
}]
}
script.js (modify setTimeout with Date.now() to get correct wait)
setTimeout(function() {
window.location = "https://www.facebook.com/"
}, 5000)
That won't work, and it's not what you want anyway.
chrome.webRequest.onBeforeRequest refers to what to decide regarding a network request before it's even sent.
First off, it stalls the network request waiting for a decision. As such, it does NOT allow a redirect to happen asynchronously - you have to decide right now, not in 5 seconds.
Second, it seems like you want the page to load, but in 5 seconds be redirected somewhere else - not keep "loading" for 5 seconds. Then webRequest is the wrong place to look.
What you want is a content script, a piece of JS code that will execute in the context of a tab after it loads.
I'll leave the manifest fields an exercise for the reader, and this code will work:
// Content script
setTimeout(function() {
window.location = "https://example.com/";
}, 5000);