How to Access a Local Node Server Using Websockets


The AngularJS web application that I’m working on runs on a remote server, but needs to access laboratory instruments connected to the local computer that is running the web browser. JavaScript running in the web browser runs in a sandbox and is prohibited from accessing local hardware.

We explored several possibilities of how to work around this and found a fairly simple solution. The local computer runs a small Node.js program to act as glue between the instrument and the local web browser. Node.js communicates with the instrument’s USB serial port using the Node serialport plugin.

Node also runs express to serve up a simple AngularJS web application for diagnostics. We also connect to the express instance to provide an interactive communication pipeline between the Node.js program and the main web application.

The Problem Space

One of the traditional iron clad security paradigms of web programming is that JavaScript served up from a server cannot access another server. This works for nearly all web sites, but there are instances where being able to share resources across servers is desirable. For example, if our web app can communicate with local laboratory instruments it’s a big win for my client.

The Approach

The W3C has published Cross-Origin Resource Sharing specifications which provide a standardized method for doing this. To implement this, the non-origin server (in our case, the Node.js server) has to provide HTTP headers to the web browser indicating that it will accept the cross-origin request.

If these headers are missing, the web browser will not complete the HTTP request. For example, Firefox 29 — in its debug console — will report

Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at http://localhost:8888/ This can be fixed by moving the resource to the same domain or enabling CORS.

This means that the web browser is denying access to Node.js running on localhost because (a) it is a different destination than the original server (the origin) and (b) the Node.js server is not granting permission for the cross-origin request.

Thus the problem boils down to coaxing to provide those headers when the web browser connects.

The Snag

I have not been able to get this to work on version 1.0 and higher. To avoid wasting time I reverted to pre-1.0 thus:

npm install --save"<1.0"

In the Node.js program’s main app.js, I added one line to allow connections from any cross-origin server (see line 2 below). Note that this is development code running on an isolated network inaccessible from the Internet. One should think hard before leaving this open to all comers.

var io = require('').listen(server);
io.set('origins', '*:*');

If you look in the source file ./lib/manager.js you’ll see the lines:

  if (origin) {
    headers['Access-Control-Allow-Origin'] = origin;
    headers['Access-Control-Allow-Credentials'] = 'true';

This may prove useful during debugging if adding the set('origins' ... call doesn’t work as expected.

Unanswered Questions

This solution doesn’t appear to work for version 1.0 and higher.


Cross-Origin Resource Sharing official W3C documentation.

Using CORS introduction to CORS.

Enable Cross-Origin Resource Sharing sample code. doesn’t set CORS header(s) on Stackoverflow





This entry was posted in Micro & Hardware, Programming and tagged , , , , , . Bookmark the permalink.