Insert into MySQL from Chrome Extension - mysql

I like to click my chrome extension and it takes the current tabs url and inserts it into a MySQL database. It seems I have to use an xhr, however I a loose grasp of how it works. I also slightly get the idea Chrome Extension → Web App API → MySQL.
So far I have a working chrome extension that grabs the current tabs url and displays it and a php file connecting to my database. However I could use some help getting to url variable to a Web API then to my php file.
Lastly, I am a bit of a newbie so I apologize if this is questioned poorly.
Edit
Here is my code and more details...
currentUrl.js
//grab the current url
chrome.tabs.getSelected(null, function(tab) {
var tabId = tab.id;
tabUrl = tab.url;
document.write(tabUrl);
});
popup.html
<!doctype html>
<html>
<head>
<script src="currentUrl.js"></script>
<script language="javascript" type="text/javascript">
</head>
</html>
insertdb.php
<?php
$con=mysqli_connect("localhost","root","my_pw","my_db");
// Check connection
if (mysqli_connect_errno())
{
echo "Failed to connect to MySQL: " . mysqli_connect_error();
}
mysqli_query($con,"INSERT INTO urlHistory (Urls)
VALUES ('Url'");
mysqli_close($con);
?>
manifest.json
{
"manifest_version": 2,
"name": "Current Url",
"description": "Grab tab's current url",
"version": "1.0",
"browser_action": {
"default_icon": "url_icon.png",
"default_popup": "popup.html"
},
"permissions": [
"tabs"
// dont't I have to put something here?
]
}

You could use XHR to send the URL over to your server where insertdb.php will be listening for and storing URLs in the DB.
Some more info on relevant concepts:
MySQLi prepared statements
XMLHttpRequests
browserAction
Sample code:
(The code below is for demonstration only and it does not take into account basic concepts, such as input validation, user authorization/authentication, error handling etc (all of which are essential for a production-ready solution).)
In insertdb.php:
<?php
if (isSet($_POST['url'])) {
$con = mysqli_connect('localhost', 'root', 'my_pw', 'my_db');
...
$stmt = mysqli_prepare($con, 'INSERT INTO urlHistory (Urls) VALUES (?)');
mysqli_stmt_bind_param($stmt, 's', $_POST['url']);
mysqli_stmt_execute($stmt);
mysqli_stmt_close($stmt);
mysqli_close($con);
}
?>
In background.js:
function sendCurrentUrl(url) {
var req = new XMLHttpRequest();
req.addEventListener('readystatechange', function (evt) {
if (req.readyState === 4) {
if (req.status === 200) {
alert('Saved !');
} else {
alert("ERROR: status " + req.status);
}
}
});
req.open('POST', 'https://your_domain/your/path/insertdb.php', true);
req.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
req.send('url=' + encodeURIComponent(url));
}
chrome.browserAction.onClicked.addListener(function (tab) {
sendCurrentUrl(tab.url);
});
In manifest.json:
{
"manifest_version": 2,
"name": "Test Extension",
"version": "0.0",
"background": {
"persistent": false,
"scripts": ["background.js"]
},
"permissions": [
"activeTab",
"https://your_domain/*"
]
}

Related

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

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({});
}
});

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!

Java + Native messaging doesn't work good

I have a problem with Java application and Google Chrome due to NPAPI deprecation..
Reading some articles and blogs, I've found a "solution" : Native Messaging.
But all the examples were made in C++/C#/Python, and for Java there is nothing..
I would like if someone could help me with this..
Here's my schema (see image):
Google chrome Extension -> Native messaging -> Java App (jar)
Problem:
The extension calls the Java app, the Java app runs but doesn't receive anything and when it returns, nothing comes to extension.
Here's my code:
Chrome extension
background.js:
chrome.runtime.onConnect.addListener(function(port) {
port.onMessage.addListener(
function(message) {
chrome.tabs.query({active: true, currentWindow: true}, function(tabs) {
console.log( 'background.js received msg [' + message.text + ']');
console.log( 'port.postMessage({content: "generated by background.js"}); to [' + tabs[0].id + "/" + tabs[0].url + ']');
chrome.runtime.sendNativeMessage('cnb.digitalsigning',message,function(response) {
console.log("Received from native " + response);
});
chrome.tabs.sendMessage(tabs[0].id, {content: "generated by background.js"});
});
return true;
});
port.onDisconnect.addListener(function() {
console.log("Background.js Port disconnected");
});
});
//native messaging
content_script.js
window.addEventListener("message", function(event) {
// We only accept messages from ourselves
if (event.source != window)
return;
if (event.data.type && (event.data.type == "DIGITAL_SIGNER_MSG")) {
console.log("Content script received from webpage: " + event.data.text);
console.log('calling port.postMessage(event.data.text); ...' + event.data.text );
port = chrome.runtime.connect();
port.postMessage({text: event.data.text});
}
}, false);
chrome.runtime.onMessage.addListener(
function(response, sender, sendResponse) {
alert("receiving response from extension" + response.content );
});
manifest.json
{
"name": "Test",
"description": "Test",
"version": "0.1",
"manifest_version": 2,
"background": {
"persistent" : true,
"scripts": ["background.js"]
},
"content_scripts": [
{
"matches": ["*://*/*"],
"js": ["content_script.js"]
}
],
"permissions": [
"nativeMessaging"
]
}
HTML
<html>
<script>
function myFunc(){
console.log('call func');
window.postMessage({ type: "DIGITAL_SIGNER_MSG", text: "do it, baby!" }, "*");
console.log('func called');
}
</script>
<body>
<div>Page</div>
<form>
<button id="caller" onclick="myFunc()">Call Extension</button>
<div id="reponseDiv" style="border: 3px; border-color: blue;">NO RESPONSE LOADED</div>
</form>
</body>
</html>
Host
installReg.bat
REG ADD "HKCU\Software\Google\Chrome\NativeMessagingHosts\digitalsigning" /ve /t REG_SZ /d "%~dp0digitalsigning.json" /f
pause
launch.bat
C:\location\to\Java\jre\bin\java.exe -cp C:\component\target\java.jar com.org.App
pause
digitalsigning.json
{
"name": "digitalsigning",
"description": "digitalsigning",
"path": "c:\\place\\launch.bat",
"type": "stdio",
"allowed_origins": [
"chrome-extension://<GOOGLE EXTENSION ID GENERATED>/"
]
}
The aplication contains a Main that captures the message using System.in.read and response to extension using System.out.write..
How could I do this communication?
Is this the correct way to start the java app?
At https://stackoverflow.com/a/25617143/865284 you can see how to send data in a proper way. System.in should be the correct way, but by now, i didn't find a way to receive data in java.
Note also this post, where sent and returned messages are sent successfully using only a few simple lines of code: https://stackoverflow.com/a/33113627. It should make it clear what the basic requirements of returned messages are.
You can take a look at https://github.com/Cosium/web-native-messaging-host .
It is a java library allowing to turn any JVM application into a Web Native Messaging Host .

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.

Chrome Extension background script not working

AIM : when ever new tab is opened extension makes a request with the url to server and get the response and change the icon color .
background.js :
chrome.tabs.onUpdated.addListener(function (tabId, changeInfo, tab)
{
url = "http://localhost/test.php?"+ $.param({"url":tab.url});
$.get(url, function(responseText) {
console.log("sent data");
});
});
manifest.json :
..."background": { "scripts": ["background.js"] ,"persistent": false },
"permissions": ["tabs","http://localhost/", "http://*/*"],....
this doesnt works .
but when binded with a button on extension page as :
function send_url(){
chrome.tabs.getSelected(null,function(tab){
url = "http://localhost/test.php?"+ $.param({"url":tab.url});
$.get(url, function(responseText) {
console.log("url sent ");
});
});
}
this sends the url to my local server !
is there any thing which is missing with background.js
This is what i was looking for :
"background": { "scripts": ["assets/js/jquery.min.js","background.js"] ,"persistent": false },