Receiving Error in Chrome Extension: Unchecked runtime.lastError: Could not establish connection. Receiving end does not exist - google-chrome

I'm trying to create a very simple Chrome extension that will allow me to highlight a word on a webpage, right click to open the context menu, and then search it on a database called Whitaker's Words by simply appending the word to the search URL. I'm continuing to receive
"Unchecked runtime.lastError: Could not establish connection. Receiving end does not exist."
as an error every time I run the code and attempt to use the context menu.
At the moment, I have already taken the steps to disable all other extensions and I attempted to use the port documentation on the Chrome Messaging Docs but I wasn't able to resolve the issue that way.
background.js
chrome.contextMenus.create({
title: "Search Whitaker's Words",
contexts: ["selection"]
});
chrome.contextMenus.onClicked.addListener(function() {
chrome.runtime.sendMessage({ method: "getSelection" }, function (response) {
sendToWW(response.data);
});
});
function sendToWW(selectedText) {
var serviceCall = 'http://archives.nd.edu/cgi-bin/wordz.pl?keyword=' + selectedText;
chrome.tabs.create({ url: serviceCall });
}
Here, I create a context menu and when the menu item is clicked, I send a message to the context script asking for the highlighted selection. I then return this to another function in background.js that will create a new tab with the search query.
content.js
chrome.runtime.onMessage.addListener(function (message) {
if (message.method === "getSelection"){
var word = window.getSelection().toString().trim();
console.log(word);
chrome.runtime.sendMessage({ data: word });
}
else
chrome.runtime.sendMessage({}); // snub them.
});
I listen here for the message and then take a selection from the window, trim, and send it back.
manifest.json
{
"manifest_version": 2,
"name": "Latinate",
"version": "0.1",
"description": "Aid in Latin translation using Whitaker's Words",
"content_scripts": [
{
"matches": [
"<all_urls>"
],
"js": [
"jquery-3.4.1.min.js",
"content.js"
]
}
],
"background": {
"scripts": [
"background.js"
]
},
"permissions": [
"contextMenus",
"tabs"
],
"browser_action": {
"default_icon": "icon.png",
"default_popup": "popup.html"
}
}
Any and all help would be appreciated! I've tried nearly everything I could find that seemed to apply.

The error message says there is no message listener on the other side. And indeed there is none because a message listener is a function registered with chrome.runtime.onMessage.addListener - in your extension only the content script has such a listener.
Instead of sending a new message back, send the response using sendResponse function which is passed as a parameter to the onMessage listener
(see also the messaging tutorial).
Another problem is that to send a message to a tab you need to use a different method: chrome.tabs.sendMessage with a tab id as the first parameter.
background script:
chrome.contextMenus.onClicked.addListener((info, tab) => {
chrome.tabs.sendMessage(tab.id, {method: 'getSelection'}, response => {
sendToWW(response.data);
});
});
content script:
chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
if (message.method === 'getSelection') {
var word = window.getSelection().toString().trim();
console.log(word);
sendResponse({ data: word });
} else {
sendResponse({});
}
});

Related

How to read a cookie in chrome extension to make sure user is logged in on my website

I have a user who will log in to my website using credentials (Not google Oauth). Once he is logged in, I want to check if he is logged in on my website using the chrome extension.
Manifest.json
"host_permissions": [
"*://*.mydomain.com/"
],
"permissions": [
"storage",
"cookies"
],
background.js
function getCookies(domain, name, callback) {
chrome.cookies.get({"url": domain, "name": name}, function(cookie) {
if(callback) {
callback(cookie.value);
}
});
}
chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {
getCookies("mydomain.com", "my_cookie_name", function (cookie_value) {
chrome.extension.getBackgroundPage().console.log(cookie_value)
});
})
Content Script
This sends messages to background.js
chrome.runtime.sendMessage({text, style, platform, isBig: Boolean(element)}, function (response) {
updateInput(response, element);
})
I don't see any log output here. Anything I am doing wrong?

Can't inject JavaScript into new tab from popup.js

I'M creating an extension that autofill's forms on different websites. There is a portion of the script that records the actions of the user with event listeners. After the recording is done the user click the test button that will launch a new tab and autofill's the form. I know launching a new tab for testing is not necessary but this function will be used later for another feature.
This is what I got so far. I had started over several times. I tried sending a message to content script. The chrome.windows,create function only launched from the popup script. I started chrome development a week ago. I'm totally confused.
Popup.js
`(async () =\> { const tab = await chrome.tabs.create({url: 'https://www.listyourself.net/ListYourself/listing.jsp'});
const tabId = tab.id; if (!tab.url)
await onTabUrlUpdated(tabId);
await chrome.scripting.executeScript({
target: {tabId},
files: \['test.js'\],
});`
})();`
I think your extension has two problems.
onTabUrlUpdated is not defined.
Execution of chrome.tabs.create causes the popup to lose focus, so the JavaScript is also terminated.
Here is a sample that fixes it.
manifest.json
{
"manifest_version": 3,
"name": "hoge",
"version": "1.0",
"permissions": [
"scripting"
],
"host_permissions": [
"<all_urls>"
],
"background": {
"service_worker": "background.js"
},
"action": {
"default_title": "hoge"
}
}
background.js
chrome.action.onClicked.addListener(() => {
main();
});
const test = () => {
console.log("test");
}
const main = async () => {
const tab = await chrome.tabs.create({ url: "https://nory-soft.web.app/" });
const tabId = tab.id;
if (!tab.url) {
chrome.tabs.onUpdated.addListener((updateTabId, changeInfo) => {
if ((updateTabId == tabId) && (changeInfo.status == "complete")) {
chrome.scripting.executeScript({
target: { tabId },
func: test
});
}
});
}
}

Can't capture screenshot on click, if a new tab opens immediately - chrome extension

I am building a chrome extension that captures the screenshot (tab) on clicking, say, hyperlink. The current Tab is not being captured if a new tab opens on clicking the hyperlink or a button.
Error:
Unchecked runtime.lastError: Cannot access contents of URL "". Extension manifest must request permission to access this host.
How can I capture the current tab in this scenario (not the new tab)?
In the example below, dataUrl (screenshot data) will be null if clicked on the first link.
The new tab opens quickly, and by the time function is being executed in the background script, the focus is on the new tab (see current tab id).
To reproduce:
index.html
<a id="first" href="https://www.example.org" target="_blank">Open link in new tab</a> <br>
<a id="second" href="https://www.example.org">Open link in same tab</a>
manifest.json
...
"content_scripts": [
{
"matches": ["<all_urls>"],
"js": ["content.js"],
"css": ["content.css"]
}
],
"host_permissions": ["<all_urls>","*://localhost:8080/*"],
"permissions": [
"activeTab",
"tabs"
],
...
content.js
/////////////// Capture tab on mouse click ///////////////
document.addEventListener("click", (e) => {
chrome.runtime.sendMessage({ msg: "capture"}, function (response) {
});
console.log("inside click eventListener");
}, true);
background.js
chrome.runtime.onMessage.addListener(function (request, sender, sendResponse) {
chrome.tabs.query({ active: true, currentWindow: true }, function (tabs) {
console.log("Current tab id", tabs[0].id);
console.log("Sender tab id", sender.tab.id);
});
chrome.tabs.captureVisibleTab(
null,
{
format: "png",
quality: 100,
},
function (dataUrl) {
console.log(dataUrl);
}
);
return true;
});
Please let me know if you need additional details. Thanks in advance!

Chrome extension sendResponse not working

There are numerous versions of this question, and I have reviewed them and tried many things to the best of my ability without success. I am new to chrome extensions, and I could be missing many things, but I don't know what.
First, I want to point out that I have copied several claimed working examples from various answers, and none of them work for me. I am using Chrome Version 58.0.3029.81 on Windows 7 Professional.
Whether it's my code, or examples I have copied, the code in the content script executes, and calls sendResponse with the correct response. Beyond that, nothing - the specified callback function is never executed.
Here is my current code:
manifest.json
{
"manifest_version": 2,
"name": "TestExtension",
"description": "...",
"version": "1.0",
"content_scripts": [
{
"matches": [
"http://*/*",
"https://*/*"
],
"js": [ "content.js" ]
}
],
"browser_action": {
"default_icon": "icon.png",
"default_popup": "popup.html",
"default_title": "Send a checkpoint request"
},
"permissions": [
"activeTab",
"tabs",
"http://*/*", // allow any host
"https://*/*" // allow any secure host
]
}
popup.js
document.addEventListener('DOMContentLoaded', function ()
{
document.getElementById('extension_form').onsubmit = function ()
{
var elementName = "DataAccessURL";
chrome.tabs.query(
{
active: true,
currentWindow: true
},
function (tabs)
{
chrome.tabs.sendMessage(
tabs[0].id,
{ Method: "GetElement", data: elementName },
function (response)
{
debugger;
console.log("response:Element = " + response.Element);
alert(response.Element);
});
});
};
});
content.js
chrome.runtime.onMessage.addListener(function (request, sender, sendResponse)
{
console.log("In Listener");
if (request.Method && request.Method == "GetElement")
{
var result = "";
var element = request.data;
console.log(element);
var e = document.getElementById(element);
if (e) result = e.innerHTML;
console.log(result);
sendResponse({ Element: result });
return true; // <-- the presence or absence of this line makes no difference
}
});
Any clues would be appreciated. I simply do not understand why my callback is not being called.
User wOxxOm provided this answer in his comments.
In the popup.js example, I am attaching to the form 'onsubmit' event to trigger my code.
I had previously read that if the popup gets closed, it's code would no longer be there to be run. I could not visually tell in my case that, as wOxxOm pointed out, that the submit event reloads the popup. That was disconnecting my code.
In order to prevent the popup from reloading, I needed to prevent the default action on the submit event. I added an 'evt' parameter to accept the event argument to the submit, and called preventDefault as shown below.
document.getElementById('extension_form').onsubmit = function (evt)
{
evt.preventDefault();
...
This allowed the sample to work as expected.
Thanks wOxxOm!

Open new tab with chrome extension an inject css with jQuery

I use a chrome extension with a popup to inject a website and hide some divs.
The problem now is, I want to open a new tab with the
url: https://app.example.de/dashboard/ and inject the style with my contentscript.js
Another problem is: Sometimes the application reloads the page. After this, all injections are lost. Is there any chance to inject allways the https://app.example.de/dashboard/ without click on the popup.html-Button?
The following code works fine, if the page is already open.
manifest.json
{
"name": "example stealth mode",
"version": "1.1",
"description": "lorem ipsum",
"browser_action": {
"default_icon": "icon-on.png",
"default_popup": "popup.html",
"default_title": "example stealth mode"
},
"manifest_version": 2,
"content_scripts": [
{
"matches": ["https://*.app.example.de/*"],
"js": ["jquery-1.11.0.min.js", "background.js"]
}
],
"background": {
"scripts": ["background.js"]
},
"permissions": [
"tabs", "https://*.app.example.de/*"
]
}
popup.js
document.addEventListener('DOMContentLoaded', function () {
document.getElementById('On').addEventListener('click', clickHandlerOn);
})
// An
function clickHandlerOn(e) {
chrome.extension.sendMessage({directive: "popup-click"}, function(response) {
this.close(); // close the popup when the background finishes processing request
});
}
background.js
chrome.extension.onMessage.addListener(
function(request, sender, sendResponse) {
switch (request.directive) {
case "popup-click":
// execute the content script
chrome.tabs.executeScript(null, { // defaults to the current tab
file: "contentscript.js", // script to inject into page and run in sandbox
allFrames: true // This injects script into iframes in the page and doesn't work before 4.0.266.0.
});
sendResponse({}); // sending back empty response to sender
break;
default:
// helps debug when request directive doesn't match
alert("Unmatched request of '" + request + "' from script to background.js from " + sender);
}
}
);
contenscript
$(document).ready(function() {
$('div#hlXXXContent').hide();
$('#hlYYY').hide();
$('#hlZZZ').hide();
$('h3.hlVVV').append(' Stealth Mode');
});
popup.html
<li><button class="hl123" id="On"><span class="hlSubmenuSelected">Stealthmode on</span</button></li>
The filename contentscript.js is odd because it's not a content script as you're using it. Why don't you try experimenting with run_at and have something load on each target page load, and that'll be your opportunity for your code to decide whether to do more things to the page.