I'm trying make a chrome extension which shows a notification when I get a message from socket.io node.js server.
Can I firstly say I have looked around a lot; some people have had similar errors but I can't seem to understand the answers and how to correct them on my PC because mine may have a different layout. Talking individually like this is better in my opinion.
This is what I have in my directory extension entitled "Projects":
My extension directory
In content.js : Uncaught ReferenceError: io is not defined
var socket = io.connect('http://localhost:1337');
socket.on("hello",function(data){
console.log(data.text);
chrome.runtime.sendMessage({msg:"socket",text:data.text},function(response){});
});
In manifest.json :
{
"background": {
"scripts": [ "background.js" , "socket.io.js"]
},
"content_scripts": [ {
"js": [ "content.js" ],
"matches": ["http://*/*", "https://*/*"]
} ],
"manifest_version": 2,
"version":"1",
"name": "MyExtension"
}
In background.js :
chrome.runtime.onMessage.addListener(
function(request,sender,senderResponse){
if(request.msg==="socket"){
console.log("receive from socket server: "+request.text);
}
}
);
And finally, app.js, my server :
var app = require('http').createServer(handler).listen(1337);
var io = require('socket.io').listen(app);
function handler(req,res){
console.log(req.url);
res.writeHead(200, {'Content-Type':'text/plain'});
res.end('Hello Node\n You are really really awesome!');
}
io.sockets.on('connection',function(socket){
socket.emit('hello',{text:"node!"});
});
This is what is inside node_modules. NOTE : THE ONLY NPM I HAVE INSTALLED IS SOCKET.IO
Inside node_modules
Related
Introduction
I am learning from JS (after messing up with Java for a bit) and I stumbled upon sockets in javascript.
Problem
I've made a python server which is listening, then I loaded the JS extension to Chrome but the server does not get any message. Where I did wrong or what I am missing?
manifest.Json (maybe it's relevant as I couldn't do this .js as "background")
{
"manifest_version": 2,
"name": "Server-Test-Ext",
"version": "0.1",
"content_scripts": [
{
"matches": ["<all_urls>"],
"js": ["socket.js", "client.js"]
}]
}
client.js ( example from the Socket.io website)
var socket = new io.Socket();
socket.connect('https://localhost:8080');
socket.on('connect', function(){
// connected!
});
socket.on('message', function(msg){
// message coming
});
socket.send('Hello world!');
server.py
import socket
HOST = '127.0.0.1'
PORT = 8080
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
s.bind((HOST, PORT))
s.listen()
conn, addr = s.accept()
with conn:
print('Connected by', addr)
while True:
data = conn.recv(1024)
if not data:
break
conn.sendall(data)
The server creates successfully the tcp (You can see that by typing on the CMD netstat -an))
Notes:
- I am using Visual Studio Code (cool text editor, still learning it)
- I am new to the subject (self-taught)
My expectation was to receive the message on the python server, which is running before the ext. Obviously.
Thanks for the interest in this question.
you need to declare socket permission to your manifest.js.
details:
https://developer.chrome.com/apps/manifest/sockets
I have written a chrome extension which loads in the developer window. It communicates with the currently loaded webpage and stores the desired data in the database.
I want to write automated unit test for this extension in node using selenium, phantomjs/chromedriver, mocha and chai.
I have written a simple test using selenium, chromedriver, mocha and chai. It is failing right now. I have attached the error below.
This is how it looks:
client.js
exports.client = require('/usr/local/lib/node_modules/webdriverjs').remote({
// Settings
// Use webdriverjs to create a Selenium Client
desiredCapabilities: {
browserName: 'chrome',
chromeOptions: {
binary: '/Applications/Google Chrome.app/Contents/MacOS/Google Chrome',
args: [],
extensions: ['/Users/Divyanshu/Downloads/STM_UPDATED_20160308051700.crx']
}
},
logLevel: 'silent'
});
test.js
var client = require('./client').client;
var expect = require('chai').expect;
describe('Test stackoverflow.com', function(){
before(function(done) {
client.init().url('chrome-extension://bfedbpidmfabedhnemcibiciahnjdnid/index.html', done);
});
describe('Check homepage', function(){
it('should see the correct title', function(done) {
client.getTitle(function(err, title){
expect(title).to.have.string(
'STM'
);
done();
});
});
it('should see the body', function(done) {
client.getText('#header', function(err, span){
expect(span).to.have.string(
'Browser'
);
done();
})
});
});
after(function(done) {
client.end();
done();
});
});
This is how I am running selenium server:
java -jar ~/Downloads/selenium-server-standalone-2.53.0.jar -Dwebdriver.chrome.driver=node_modules/chromedriver/bin/chromedriver
And this is how I am running my test:
mocha test.js -t 10000
But I am not able to load my extension and getting these error:
Error output of test run:
Test stackoverflow.com
[13:08:00]: COMMAND POST {"protocol":"http:","slashes":true,"auth":null,"host":"127.0.0.1:4444","port":"4444","hostname":"127.0.0.1","hash":null,"search":null,"query":null,"pathname":"/wd/hub/session","path":"/wd/hub/session","href":"http://127.0.0.1:4444/wd/hub/session"}
[13:08:00]: DATA {"desiredCapabilities":{"browserName":"chrome","version":"","javascriptEnabled":true,"platform":"ANY","chromeOptions":{"binary":"/Applications/Google Chrome.app/Contents/MacOS/Google Chrome","args":[],"extensions":["/Users/Divyanshu/Downloads/STM_UPDATED_20160308051700.crx"]}}}
[13:08:00]: ERROR UnknownError An unknown server-side error occurred while processing the command.
unknown error: cannot process extension #1
from unknown error: cannot base64 decode
(Driver info: chromedriver=2.21.371459 (36d3d07f660ff2bc1bf28a75d1cdabed0983e7c4),platform=Mac OS X 10.11.4 x86_64) (WARNING: The server did not provide any stacktrace information)
[13:08:00]: ERROR Couldn't get a session ID - undefined
1) "before all" hook
[13:08:00]: COMMAND DELETE {"protocol":"http:","slashes":true,"auth":null,"host":"127.0.0.1:4444","port":"4444","hostname":"127.0.0.1","hash":null,"search":null,"query":null,"pathname":"/wd/hub/session/","path":"/wd/hub/session/","href":"http://127.0.0.1:4444/wd/hub/session/"}
[13:08:00]: DATA {}
0 passing (730ms)
1 failing
1) Test stackoverflow.com "before all" hook:
Uncaught Error: [init()] <=
An unknown server-side error occurred while processing the command.
at makeError (/usr/local/lib/node_modules/webdriverjs/lib/utils/makeError.js:9:17)
at RequestHandler.<anonymous> (/usr/local/lib/node_modules/webdriverjs/lib/utils/RequestHandler.js:170:25)
at Request.self.callback (/usr/local/lib/node_modules/webdriverjs/node_modules/request/request.js:122:22)
at Request.<anonymous> (/usr/local/lib/node_modules/webdriverjs/node_modules/request/request.js:1019:14)
at IncomingMessage.<anonymous> (/usr/local/lib/node_modules/webdriverjs/node_modules/request/request.js:970:12)
at endReadableNT (_stream_readable.js:913:12)
Error output in selenium server: Exception: unknown error: cannot process extension #1
I used fs.readFileSync('/Users/Divyanshu/Downloads/STM_UPDATED_20160308051700.crx', 'base64') to encode my crx file to overcome this error and got the error:
Exception: unknown error: cannot parse capability: chromeOptions
I then tried to load the extension without crx file. Added this in 'args' in 'chromeOptions':
args: ['load-extension=/Users/Divyanshu/Downloads/STM_UPDATED_20160308051700']
This helped me in resolving the error: cannot process extension #1
But now I have stumbled upon new error. I am not able to load my html file (index.html). Its saying "Your file was not found. It may have been moved or deleted. ERR_FILE_NOT_FOUND. Reload". How can I over come this error?
This is how my manifest.json file looks:
{
"name": "Extension",
"description": "Tool.",
"icons": {
"16": "icons/icon16.png",
"48": "icons/icon48.png",
"128": "icons/icon128.png"
},
"version": "1.1.2",
"manifest_version": 2,
"permissions": [
"webRequest",
"<all_urls>",
"history",
"background",
"storage",
"cookies",
"clipboardWrite",
"tabs"
],
"options_page": "options.html",
"background": {
"scripts": [
"background-script.js",
"panes/js/jquery.js"
]
},
"content_security_policy": "script-src 'self' 'unsafe-eval'; object-src 'self'",
"devtools_page": "devtools.html",
"web_accessible_resources": [
"panes/*"
]
}
and this is my devtools.js file which I load from an html file where I have specified the location of devtools.html:
var panelWindow, injectedPanel = false, injectedPage = false,
panelVisible = false, savedStack = [];
chrome.devtools.panels.create("Extension", "panes/img/logo.jpg",
"panes/index.html", function(panel) {});
So, my extension has multiple html files. And I want to write unit tests for all those, moving past each file one by one, like, first I have to log into my extension (this is login.html), then I will select a client (this is selectClient.html) etc etc.
index.html loads first as you can see from the devtools.js, from where all the processing starts and loads other html files one by one.
I am implementing communication between a web page and a Mac application using Chrome's Native Messaging feature. All seems to go well until I make the javascript call to chrome.runtime.connectNative("my_native_host_app_name"), which produces the following error in the console:
Error in event handler for runtime.onMessageExternal: Error connecting to native app: com.allinlearning.nmhforbrowserextension
Stack trace: Error: Error connecting to native app: com.allinlearning.nmhforbrowserextension
at Object.<anonymous> (extensions::runtime:189:11)
at Function.target.(anonymous function) (extensions::SafeBuiltins:19:14)
at Object.handleRequest (extensions::binding:55:27)
at Function.target.(anonymous function) (extensions::SafeBuiltins:19:14)
at Object.<anonymous> (extensions::binding:318:32)
at chrome-extension://gldheanjpgopipommeingjlnoiamdfol/background.js:19:27
at Function.target.(anonymous function) (extensions::SafeBuiltins:19:14)
at EventImpl.dispatchToListener (extensions::event_bindings:395:22)
at Function.target.(anonymous function) (extensions::SafeBuiltins:19:14)
at Event.$Array.forEach.publicClass.(anonymous function) [as dispatchToListener] (extensions::utils:65:26) extensions::event_bindings:383
EventImpl.dispatch_extensions::event_bindings:383
EventImpl.dispatchextensions::event_bindings:401
$Array.forEach.publicClass.(anonymous function)extensions::utils:65
messageListenerextensions::messaging:190
EventImpl.dispatchToListenerextensions::event_bindings:395
$Array.forEach.publicClass.(anonymous function)extensions::utils:65
EventImpl.dispatch_extensions::event_bindings:378
EventImpl.dispatchextensions::event_bindings:401
$Array.forEach.publicClass.(anonymous function)extensions::utils:65
dispatchOnMessageextensions::messaging:304
The actual call that seems to cause this error (line 19 in the ref to background.js in the stack trace) is:
port = chrome.runtime.connectNative("com.nmhforbrowserextension");
To give more context, it is invoked from a listener:
chrome.runtime.onMessageExternal.addListener(
function(request, sender, sendResponse) {
//var imgdata = JSON.stringify(request.imgdata);
//process it somehow here
port = chrome.runtime.connectNative("com.allinlearning.nmhforbrowserextension");
if (port)
console.log("connectNative() returned a non-null port");
else
console.log("connectNative() returned null for the port");
});
It never gets to the if statement. The doc I am primarily using is Chrome Native Messaging. At the bottom of the doc it has a section to provide help with common errors Debugging native messaging. I can't seem to relate the "Error connecting to native app" to any of the specifically mentioned errors.
The complete contents of my extension manifest file ("manifest.json") are:
{
"manifest_version": 2,
"name": "AIL Extension",
"version": "1.0",
"description": "New Reader",
"background": {
"scripts": ["background.js"]
},
"externally_connectable": {
// Extension and app IDs. If this field is not specified, no
// extensions or apps can connect.
"ids": [
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
],
// Match patterns for web pages. Does not affect content scripts.
// If this field is not specified, no webpages can connect.
"matches": [
"http://localhost/charles/qrexttest/*"
],
"permissions": [
"nativeMessaging",
"tabs",
"activeTab",
"background",
"http://*/", "https://*/"
],
// Indicates that the extension would like to make use of the TLS
// channel ID of the web page connecting to it. The web page must
// also opt to send the TLS channel ID to the extension via setting
// includeTlsChannelId to true in runtime.connect's connectInfo
// or runtime.sendMessage's options.
"accepts_tls_channel_id": false
}
}
One of the possible causes for the "Error connecting to native app: [native messaging host id]" is the absence of the required nativeMessaging permission.
Declare the "nativeMessaging" permission in the manifest file, reload the extension and try again.
(the fact that chrome.runtime.connectNative and sendNativeMessage are available without this permission is a bug.)
I'm programming a chrome JS extensions that uses sockets to communicate with a Java server.
When I use the following line :
var socket = chrome.socket || chrome.experimental.socket;
socket.create('tcp',{},function(createInfo) {
I get the
Error in event handler for 'tabs.onUpdated': Cannot read property 'socket' of undefined TypeError: Cannot read property 'socket' of undefined
error (the JS code is in a tabs.onUpdated function).
My manifest file is :
{
"manifest_version": 2,
"name": "MitM Phishing Detector",
"description": "This extension protects your browser against phishing attacks based on MitM attacks",
"version": "1.0",
"background": {
"scripts": ["notify.js"],
"persistent": false
},
"browser_action": {
"default_icon": "bluetooth_device.png",
"default_popup": "choose_device.html"
},
"permissions": [
"tabs",
"http://*/*",
"background",
{"socket":
[ "tcp-connect:127.0.0.1:8081" ]
},
"notifications"
]
}
If you are using the canary/experimental build of Chrome you should be able to do
chrome.experimental.socket.create('tcp', ...)
to open a TCP socket. But just calling socket.create won't work.
Remember that this will probably only ever work on chrome... WebSockets are a much more portable solution.
To set socket properly I think that this should work (havn't tested it):
var socket = chrome.socket;
if (unfefined !== chrome.experimental.socket)
socket = chrome.experimental.socket;
if (undefined === chrome.socket)
throw "Socket unavailable"
When trying to communicate between my Content- and Background Script I get the following errors:
Port error: Could not establish connection. Receiving end does not exist.
Error in event handler for 'undefined': Cannot read property 'message' of undefined
TypeError: Cannot read property 'message' of undefined
background.js
function onRequest(request, sender, callbackFunction) {
console.log("Me (BS) became this Message:" + request.message);
sendResponse({message: request.message})
};
chrome.extension.onRequest.addListener(onRequest);
streamcloud.js
function contactBackground(nachricht){
chrome.extension.sendMessage({message: nachricht}, function(response) {
console.log("The Background Script got the following Message: " + response.message);
});
}
and my manifest.json
{
"name": "InstantWatch - Dev",
"manifest_version": 2,
"version": "0.7",
"permissions": ["tabs", "http://*/", "https://*/"],
"background": {
"scripts": ["background.js"]
},
"browser_action": {
"default_title": "InstantWatch",
"default_icon" : "icon.ico"
},
"content_scripts": [
{
"matches": ["http://*/*", "http://*/*"],
"js": ["jquery.js", "streamcloud.js"]
}
]
}
I found the solution to add an background_page: "background.html" with an empty background.html, but since background_page isn't supported since manifest_version: 2, I can't use that.
sendMessage and onRequest are not compatible.
If you need to support Chrome 19 and earlier, use onRequest and sendRequest:
chrome.extension.onRequest.addListener(function(request, sender, sendResponse) {
// Warning: Chrome 19- [receiver]
});
chrome.extension.sendRequest(message, optional_sendResponse);
For Chrome 20 - 25, use chrome.extension.onMessage and chrome.extension.sendMessage:
chrome.extension.onMessage.addListener(function(request, sender, sendResponse) {
// Chrome 20+
});
chrome.extension.sendMessage(message, optional_sendResponse);
For Chrome 26+, use chrome.runtime.onMessage and chrome.runtime.sendMessage.
Note: As of Chrome 26, the deprecated methods are still supported, albeit undocumented. If you get a chance, update your extension to use the new methods, to ensure that your extension will still work in the future.
See this answer for code to create a which is compatible with Chrome 20+.
Instead of
chrome.extension.onRequest.addListener(onRequest);
Use
chrome.extension.onMessage.addListener(onRequest);
Since you are using sendMessage and not sendRequest.
Message parsing has been updated in the new version of Chrome. sendRequest and onRequest are being deprecated. It is recommended to go with sendMessage and onMessage.
Refer docs for message parsing between Content Script and Background.