chrome.runtime.connectNative from external url - javascript

I have a Google Chrome extension which contains the following two files...
manifest.json
{
"key": "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDcBHwzDvyBQ6bDppkIs9MP4ksKqCMyXQ/A52JivHZKh4YO/9vJsT3oaYhSpDCE9RPocOEQvwsHsFReW2nUEc6OLLyoCFFxIb7KkLGsmfakkut/fFdNJYh0xOTbSN8YvLWcqph09XAY2Y/f0AL7vfO1cuCqtkMt8hFrBGWxDdf9CQIDAQAB",
"name": "Native Messaging Example",
"version": "1.0",
"manifest_version": 2,
"description": "Send a message to a native application.",
"app": {
"launch": {
"local_path": "index.html"
}
},
"icons": {
"128": "icon-128.png"
},
"permissions": [
"nativeMessaging"
],
"externally_connectable": {
"matches": ["*://*.chrome-extension.com/*"]
},
"background": {
"scripts": ["background.js"]
}
}
background.js
var sendResponseCallBack;
chrome.runtime.onMessageExternal.addListener(
function(request, sender, sendResponse) {
sendResponseCallBack = sendResponse;
var message = {"comment": '*** ' + request['comment'] + ' ***'};
var useNative = false;
if (useNative) {
connect();
sendNativeMessage(message);
}
else {
sendResponseCallBack(message);
}
}
);
function connect() {
var hostName = "com.google.chrome.example.echo";
port = chrome.runtime.connectNative(hostName);
port.onMessage.addListener(onNativeMessage);
port.onDisconnect.addListener(onDisconnected);
}
function sendNativeMessage(message) {
port.postMessage(message);
}
function onNativeMessage(message) {
port.disconnect();
sendResponseCallBack(message);
}
I also configured the virtual host: chrome-extension.com to access to the url from a local server:
http://www.chrome-extension.com/
With the Chrome extension installed and enabled, if I access to:
http://www.chrome-extension.com/
and the variable useNative = false then I get a response from the plugin through: sendResponseCallBack(message);, but if useNative = true then I don't get any response from the plugin, I get: undefined and also the native operation which should take about 5 seconds, doesn't go thru because the undefined response is returned in 0 seconds.
I also have enabled another html page I access thru the extension url:
chrome-extension://knldjmfmopnpolahpmmgbagdohdnhkik/calc-with-os.html
Inside that page I include the calc-with-os.js file which contains the above functions: connect() sendNativeMessage(message) onNativeMessage(message) and the function: chrome.runtime.connectNative works properly performing the native process in all its phases.
Any idea on how can I connect to a native process from an external url?
[EDIT: TRY NUMBER 2]
Based on the comment of: #wOxxOm I did the following modification to the code with the purpose of don't send the message to fast and wait for the native process to start, but it is not still working.
Any other suggestions?
var port = null;
var sendResponseCallBack;
chrome.runtime.onMessageExternal.addListener(
function(request, sender, sendResponse) {
sendResponseCallBack = sendResponse;
connect(request);
}
);
function connect(request) {
chrome.runtime.onConnect.addListener(function(p){
port = p;
port.onMessage.addListener(onNativeMessage);
port.onDisconnect.addListener(onDisconnected);
var message = {"comment": '*** ' + request['comment'] + ' ***'};
sendNativeMessage(message);
});
var hostName = "com.google.chrome.example.echo";
chrome.runtime.connectNative(hostName);
}
function sendNativeMessage(message) {
port.postMessage(message);
}
function onNativeMessage(message) {
port.disconnect();
sendResponseCallBack(message);
}

Related

Chrome Extension Host Registration not working in windows

I want to run console app by clicking button on webpage
Console app will get Information and put in clipboard, and then I will get that information on webpage.
I am following this blog
I did this 3-4 times, all other things looks fine, but console app is not being called/executed.
I am getting these errors.
on webpage console
Unchecked runtime.lastError: The message port closed before a response was received.
on background file
Unchecked runtime.lastError: Specified native messaging host not found.
Unchecked runtime.lastError: The message port closed before a response was received.
my codes are
manifest.json
{
"name": "EID Reader",
"version": "1.0",
"manifest_version": 2,
"description": "Read Emirates ID",
"permissions": [ "contextMenus", "activeTab", "clipboardRead", "nativeMessaging" ],
"icons": {
"16": "eid16.png",
"48": "eid48.png",
"128": "eid128.png"
},
"background": {
"scripts": [ "eid.js" ]
},
"content_scripts": [
{
"matches": [ "http://*/*", "https://*/*", "file://*/*"],
"js": [ "content_script.js", "jquery-3.3.1.js" ],
"all_frames": true,
"run_at": "document_start"
}
]
}
content_script.js
// Listener to catch the event raised by the webpage button
document.addEventListener("EID_EVENT", function (data) {
// send message to background process to read emirates ID and send back the data
chrome.runtime.sendMessage("ifligfijbkpijeafdfbpljjibfbppmeb", function (response) {
});
});
// Listener to catch the data coming from the background process
chrome.extension.onMessage.addListener(function (msg, sender, sendResponse) {
if (msg.action == 'EID_DATA') {
//Parse the data and fill the form accordingly
try {
var json = $.parseJSON(msg.response);
$(json).each(function (i, val) {
$.each(val, function (key, value) {
if (key == 'EIDNumber')
$("#txtNumber").val(value);
if (key == 'Name')
$("#txtName").val(value);
if (key == 'Email')
$("#txtEmail").val(value);
if (key == 'PassportNumber')
$("#txtPassport").val(value);
});
});
}
catch (e) {
var error = "error" + e;
}
}
});
eid.js (background)
var port = null;
var tabId = null;
/* listener for messages coming from the content_scrip */
chrome.runtime.onMessage.addListener(function (message, sender, sendResponse) {
tabId=sender.tab.id;
var hostName = "ae.eid.chrome";
port = chrome.runtime.connectNative(hostName);
port.onDisconnect.addListener(onDisconnected);
});
/* THIS WILL BE CALLED ONCE EXE FINISH */
function onDisconnected() {
port = null;
SendResponse();
}
function SendResponse() {
//create a textarea, focus on it, and make a "paste" command to get the clipboard, then send the pasted value back to the content_script
bg = chrome.extension.getBackgroundPage();
bg.document.body.innerHTML = ""; // clear the background page
var helper = null;
if (helper == null) {
helper = bg.document.createElement("textarea");
helper.style.position = "absolute";
helper.style.border = "none";
document.body.appendChild(helper);
}
//Focus the textarea
helper.select();
// perform a Paste in the selected control, here the textarea
bg.document.execCommand("Paste");
// Send data back to content_script
chrome.tabs.sendMessage(tabId, { action: "EID_DATA", response: helper.value }, function (response) { });
}
ae.eid.chrome.json
{
"name": "ae.eid.chrome",
"description": "chrome extension to read EID",
"path": "EIDSampleConsole.exe",
"type": "stdio",
"allowed_origins": [
"chrome-extension://ifligfijbkpijeafdfbpljjibfbppmeb/"
]
}
install_host.bat
REG ADD "HKCU\Software\Google\Chrome\NativeMessagingHosts\ae.eid.chrome" /ve /t REG_SZ /d "%~dp0ae.eid.chrome.json" /f
I spent 2 days didnot get anything helpful.
Am I doing some error or Google Chrome prevented or changed the way to register host.
I have solved all the issues and posted all the steps at
http://www.codingsips.com/emirates-id-reader-and-google-chrome-via-extension-and-console-app/
Also I have published chrome extension, it you follow above steps the same extension will also work for you
chrome extension
https://chrome.google.com/webstore/detail/adcs-eid-reader/ipcncgpbppgjclagpdlodiiapmggolkf

javascript - Chrome extension: Communication between content.js and background.js on load

Edit: Modified code using https://developer.chrome.com/extensions/devtools#evaluated-scripts-to-devtools as reference. Still no luck.
I'm trying to code a chrome-extension which uses chrome.* API call and save portions of the result in a file. I want to automate everything from the loading of the page to the text file download and hence, I don't want to use the browser.onclick() event.
My current attempt has no effect.
What changes would I need to make?
https://stackoverflow.com/a/16720024
Using the above answer as reference, I attempted the following:
manifest.json
{
"name":"Test Extension",
"version":"0.0.1",
"manifest_version": 2,
"description":"Description",
"permissions":["tabs"],
"background": {
"scripts": ["background.js"]
},
"devtools_page": "devtools.html"
}
background.js
// Background page -- background.js
chrome.runtime.onConnect.addListener(function(devToolsConnection) {
// assign the listener function to a variable so we can remove it later
var devToolsListener = function(message, sender, sendResponse) {
// Inject a content script into the identified tab
chrome.tabs.executeScript(message.tabId,
{ file: message.scriptToInject });
}
// add the listener
devToolsConnection.onMessage.addListener(devToolsListener);
devToolsConnection.onDisconnect.addListener(function() {
devToolsConnection.onMessage.removeListener(devToolsListener);
});
}
devtools.js
var backgroundPageConnection = chrome.runtime.connect({
name: "devtools-page"
});
backgroundPageConnection.onMessage.addListener(function (message) {
// Handle responses from the background page, if any
});
chrome.devtools.network.onRequestFinished.addListener(
function(request) {
chrome.runtime.sendMessage({
string: "Hi",
tabId: chrome.devtools.inspectedWindow.tabId,
scriptToInject: "content.js"
});
}
);
chrome.runtime.sendMessage({
string: "Hi",
tabId: chrome.devtools.inspectedWindow.tabId,
scriptToInject: "content.js"
});
content.js
alert("Hello");

XMLHttpRequest from Firefox WebExtension

I've seen loads of examples of creating xhr requests from Firefox Add-ons, but I am trying to use the new WebExtensions stuff (where require and Components are undefined) and can't seem to see why I can't send a simple XmlHttpRequest from within the extension?
It's worth noting that the ajax request is going to a completely different URL, but the host has CORs set to allow all origins.
As soon as .send() is fired I get the error:
[Exception... "Failure" nsresult: "0x80004005 (NS_ERROR_FAILURE)" location: "JS frame :: resource://gre/modules/ExtensionContent.jsm -> moz-extension://9ca18411-9a95-4fda-8184-9dcd3448a41a/myapp.js :: GM_xmlhttpRequest :: line 162" data: no]"1 whatsapp.js:166:9
The code looks like this:
function GM_xmlhttpRequest(orders) {
try {
var oReq = new XMLHttpRequest();
oReq.addEventListener("load", function(a1, a2, a3) {
console.log('xhr.load: %s, %s, %s', a1, a2, a3);
});
// open synchronously
oReq.open(orders.method, orders.url, false);
// headers
for (var key in orders.headers) {
oReq.setRequestHeader(key, orders.headers[key]);
}
// send
var res = oReq.send(orders.data);
console.log('xhr result: %s', res);
} catch(e) {
debugger;
console.warn('could not send ajax request %s to %s, reason %s', orders.method, orders.url, e.toString());
}
}
I've added webRequest permissions to my manifest.json, I realise that is not what it means, but am struggling to understand what is stopping the ajax request? Any ideas?
{
"manifest_version": 2,
"name": "MyApp",
"version": "1.0",
"description": "TestXHR",
"icons": {
"48": "icons/myapp-48.png"
},
"applications": {
"gecko": {
"id": "software#vigilantapps.com",
"strict_min_version": "45.0"
}
},
"content_scripts": [
{
"matches": ["*://web.myapp.com/*"],
"js": ["myapp.js"]
}
],
"permissions": [
"https://thehost.all-xhr-sent-here.net/*",
"webRequest"
]
}
The problem was the permissions URL specified. I changed the sub domain to an asterisk and the protocol to an asterisk and it seemed to work after that.

Chrome Extension: CRX file not working properly

I am trying to install my Extension's CRX version but it is not loading some of image files on extension button placed on address bar.I have even put try/catch but it is not giving any error either. The Developer/Unpack version is working just fine.
What's wrong am I doing? What I guess my all image files are not compressed in CRX file. Unfortunately I can't extract CRX content either as renamig to .ZIP is not letting me to unzip on MacoSX
I am installing CRX by dragging on to extensions page.
How do I test the issue?
Code is given below:
Manifest.jsonn
{
"name": "Domain Colors",
"version": "1.0",
"manifest_version": 2,
"description": "Change Button Color for domains.",
"content_scripts": [
{
"matches": ["http://*/*","https://*/*"],
"js": ["script.js"]
}
],
"permissions": [
"tabs", "http://*/*"
],
"browser_action": {
"default_title": "Colry",
"default_icon": "blue.png"
},
"background": {
"scripts": ["background41.js"]
}
}
script.js
alert("Testing Version..Wait for a while");
var request = new XMLHttpRequest();
if (request == null)
{
alert("Unable to create request");
}
else
{
try
{
var timestamp = new Date().getTime(); //to avoid cache ajax calls
var randomnumber=Math.floor(Math.random()*11);
timestamp = timestamp * randomnumber;
var _domain = document.domain;
_domain = _domain.replace("www.","");
var url = "http://xxxxnet/xxx/xxx.asp?xx="+_domain+"&ts="+timestamp;
request.onreadystatechange = function()
{
//request.setRequestHeader('Cache-Control', 'no-cache');
//request.setRequestHeader('Pragma', 'no-cache');
if(request.readyState == 4)
{
LDResponse(request.responseText);
}
}
request.open("GET", url, true);
request.send(null);
}
catch(e){
alert('An error has occurred in AJAX Call: '+e.message)
}
}
function LDResponse(response)
{
var json = JSON.parse(response);
alert(response);
var msg = document.domain+","+json["buttonColour"]+","+json["buttonTip"];
chrome.extension.sendMessage(msg);
}
background file
var currentUrl = "";
var currentColor = "";
var currentTip = "";
chrome.tabs.onUpdated.addListener(function(tabId, changeInfo) {
if (changeInfo.status === 'loading')
{
chrome.browserAction.setIcon({
path:'chrome-extension://lkhgldilknhpmdodeblhnbniahbjcdcm/gray.png',
tabId:tabId
});
chrome.extension.onMessage.addListener(function(message, sender)
{
try
{
var stuff = message.split(",");
currentUrl = stuff[0];
currentUrl = currentUrl.replace("www.","");
currentColor = stuff[1];
currentTip = stuff[2];
}
catch(e)
{
alert('An error in onMessage method: '+e.message)
}
});
}
else if (changeInfo.status === 'complete')
{
try
{
chrome.browserAction.setIcon({
path:'chrome-extension://lkhgldilknhpmdodeblhnbniahbjcdcm/'+currentColor+".png",
tabId:tabId
});
chrome.browserAction.setTitle({
tabId:tabId,
title:currentTip
});
}
catch(e)
{
alert('An error in Complete method: '+e.message)
}
}
});
Thanks
Replace path:'chrome-extension://lkhgldilknhpmdodeblhnbniahbjcdcm/'+currentColor+".png with path: chrome.extension.getURL("currentColor.png") to get it to work.
Your runtime extension id is not lkhgldilknhpmdodeblhnbniahbjcdcm, so to use dynamic generated content you should use chrome.extension.getURL()

Chrome Extension - Channels Not Working

I am trying to create a channel to my Google App Engine (Python) server, and there seems to be a problem but I am unsure why. When the user toggles the extension, it authenticates the user. If successful, the server replies with a channel token which I use to create the channel. When I authenticate the user, alert("a") appears, but alert("b") does not which makes me believe there is a problem with the line var channel = new goog.appengine.Channel(msg.token);, but the console does not report an error.
I have also copied the javascript code from here and placed it in my manifest as oppose to putting <script type="text/javascript" src="/_ah/channel/jsapi"></script> in background.html.
//script.js
function authenticate(callback) {
var url = "https://r-notes.appspot.com/init/api/authenticate.json?username=" + username + "&password=" + password;
$.post(url, function(data) {
if (data.status == "200") {
channelToken = data.channeltoken;
if (callback) {
callback();
}
var port = chrome.extension.connect({name: "myChannel"});
port.postMessage({token: channelToken});
port.onMessage.addListener(function(msg) {
console.log(msg.question);
});
}
});
}
//background.html
chrome.extension.onConnect.addListener(function(port) {
port.onMessage.addListener(function(msg) {
alert("a"); //pops up
var channel = new goog.appengine.Channel(msg.token);
alert("b"); //does not pop up
console.log(channel); //display error ' Error in event handler for 'undefined': ReferenceError: goog is not defined '
var socket = channel.open()
socket.onopen = function() {
// Do stuff right after opening a channel
console.log('socket opened');
}
socket.onmessage = function(evt) {
// Do more cool stuff when a channel message comes in
console.log('message recieved');
console.log(evt);
}
});
});
//manifest.json
{
"name": "moot",
"description": "Clicking on the moot button will display a sidebar!",
"version": "0.2.69",
"background_page": "html/background.html",
"browser_action": {
"default_icon": "img/icon_64.png",
"default_title": "moot"
},
"content_scripts": [
{
"matches": ["<all_urls>"],
"js": ["js/channelApi.js",
"js/script.js", "js/mootsOnSidebar.js", "js/mootsOnPage.js", "js/authenticate.js", "js/otherFunctions.js",
"js/jquery/jquery-1.7.1.js", "js/jquery/jquery.mCustomScrollbar.js", "js/jquery/jquery-ui.min.js",
"js/jquery/jquery.autosize.js", "js/jquery/jquery.mousewheel.min.js", "js/jquery/jquery.easing.1.3.js",
"js/channel.js"],
"css": ["css/cssReset.css", "css/sidebar.css", "css/onPageCreate.css", "css/onPageExists.css", "css/scrollbar.css", "css/authenticate.css"]
}
],
"permissions": [
"tabs", "contextMenus", "http://*/*", "https://*/"
],
"icons": {
"16": "img/icon_16.png",
"64": "img/icon_64.png"
}
}
EDIT - After doing console.log(channel), I discovered the error ' Error in event handler for 'undefined': ReferenceError: goog is not defined '. I am unsure why I receive this error as I did include the required javascript file as I followed this post.
So the solution is that you need to include the file <script type="text/javascript" src="https://talkgadget.google.com/talkgadget/channel.js"></script> in a HTML page. I placed this on the first row of background.html.
My mistake was saving a local copy of channel.js, and refer to it in manifest.json.
I'm now going to place a copy of channel.js on my server, and refer to my server's copy. I don't think there will be any issues with that.
Make a console log for the value of msg direct between alert("a") and var channel = ...
and inspect the value.

Categories

Resources