Using Node.js as a simple web server

Tutorial: Using Node.js as a simple web server

I want to run a very simple HTTP server. Every GET request to example.com should get index.html served to it but as a regular HTML page (i.e., same experience as when you read normal web pages).

Using the code below, I can read the content of index.html. How do I serve index.html as a regular web page?

var http = require('http');
var fs = require('fs');
var index = fs.readFileSync('index.html');

http.createServer(function (req, res) {
  res.writeHead(200, {'Content-Type': 'text/plain'});
  res.end(index);
}).listen(9615);

One suggestion below is complicated and requires me to write a get line for each resource (CSS, JavaScript, images) file I want to use.

How can I serve a single HTML page with some images, CSS and JavaScript?

Answers to Using Node.js as a simple web server

Answer 1: Using Node.js as a simple web server

Simplest Node.js server is just:

$ npm install http-server -g

Now you can run a server via the following commands:

$ cd MyApp

$ http-server

If you’re using NPM 5.2.0 or newer, you can use http-server without installing it with npx. This isn’t recommended for use in production but is a great way to quickly get a server running on localhost.

$ npx http-server

Or, you can try this, which opens your web browser and enables CORS requests:

$ http-server -o --cors

For more options, check out the documentation for http-server on GitHub, or run:

$ http-server --help

Lots of other nice features and brain-dead-simple deployment to NodeJitsu.

Feature Forks

Of course, you can easily top up the features with your own fork. You might find it’s already been done in one of the existing 800+ forks of this project:

Light Server: An Auto Refreshing Alternative

A nice alternative to http-server is light-server. It supports file watching and auto-refreshing and many other features.

$ npm install -g light-server 
$ light-server

Add to your directory context menu in Windows Explorer

 reg.exe add HKCR\Directory\shell\LightServer\command /ve /t REG_EXPAND_SZ /f /d "\"C:\nodejs\light-server.cmd\" \"-o\" \"-s\" \"%V\""

Simple JSON REST server

If you need to create a simple REST server for a prototype project then JSON-server might be what you’re looking for.

Auto Refreshing Editors

Most web page editors and IDE tools now include a web server that will watch your source files and auto refresh your web page when they change.

I use Live Server with Visual Studio Code.

The open-source text editor Brackets also includes a NodeJS static web server. Just open any HTML file in Brackets, press “Live Preview” and it starts a static server and opens your browser at the page. The browser will auto refresh whenever you edit and save the HTML file. This is especially useful when testing adaptive websites. Open your HTML page on multiple browsers/window sizes/devices. Save your HTML page and instantly see if your adaptive stuff is working as they all auto-refresh.

Web / SPA / PWA / Mobile / Desktop / Browser Ext Web Developers

Some SPA frameworks include a built in version of the Webpack DevServer that can detect source file changes and trigger an incremental rebuild and patch (called hot reloading) of your SPA or PWA web app. Here are a few popular SPA frameworks that can do this.

VueJS Developers

For VueJS developers, a favorite is Quasar Framework which includes the Webpack DevServer out of the box with switches to support server-side rendering (SSR) and proxy rules to cure your CORS issues. It includes a large number of optimized components designed to adapt for both Mobile and Desktop. These allow you to build one app for ALL platforms (SPA, SPA+SSR, PWA, PWA+SSR, Cordova and Capacitor Mobile AppStore apps, Electron Desktop Node+VueJS apps, and even Browser extensions).

Another popular one is NuxtJS which also supports static HTML/CSS code generation as well as SSR or no-SSR build modes with plugins for other UI component suites.

React Framework Developers

ReactJS developers can also set up hot reloading.

Cordova/Capacitor + Ionic Framework Developers

Iconic is a mobile only hybrid component framework that now supports VueJS, React, and Angular development. A local server with auto-refresh features is baked into the ionic tool. Just run ionic serve from your app folder. Even better … ionic serve --lab to view auto-refreshing side-by-side views of both iOS and Android.

Answer 2: Using Node.js as a simple web server

Note: This answer is from 2011. However, it is still valid.

You can use Connect and ServeStatic with Node.js for this:

  1. Install connect and serve-static with NPM $ npm install connect serve-static
  2. Create server.js file with this content:
 var connect = require('connect');
 var serveStatic = require('serve-static');

 connect()
     .use(serveStatic(__dirname))
     .listen(8080, () => console.log('Server running on 8080...'));

3. Run with Node.js $ node server.js

You can now go to http://localhost:8080/yourfile.html

Answer 3: Using Node.js as a simple web server

Check out this gist. I’m reproducing it here for reference, but the gist has been regularly updated.

Node.JS static file web server. Put it in your path to fire up servers in any directory, takes an optional port argument.

var http = require("http"),
    url = require("url"),
    path = require("path"),
    fs = require("fs"),
    port = process.argv[2] || 8888;

http.createServer(function(request, response) {

  var uri = url.parse(request.url).pathname
    , filename = path.join(process.cwd(), uri);

  fs.exists(filename, function(exists) {
    if(!exists) {
      response.writeHead(404, {"Content-Type": "text/plain"});
      response.write("404 Not Found\n");
      response.end();
      return;
    }

    if (fs.statSync(filename).isDirectory()) filename += '/index.html';

    fs.readFile(filename, "binary", function(err, file) {
      if(err) {        
        response.writeHead(500, {"Content-Type": "text/plain"});
        response.write(err + "\n");
        response.end();
        return;
      }

      response.writeHead(200);
      response.write(file, "binary");
      response.end();
    });
  });
}).listen(parseInt(port, 10));

console.log("Static file server running at\n  => http://localhost:" + port + "/\nCTRL + C to shutdown");

Update

The gist does handle css and js files. I’ve used it myself. Using read/write in “binary” mode isn’t a problem. That just means that the file isn’t interpreted as text by the file library and is unrelated to content-type returned in the response.

The problem with your code is you’re always returning a content-type of “text/plain”. The above code does not return any content-type, but if you’re just using it for HTML, CSS, and JS, a browser can infer those just fine. No content-type is better than a wrong one.

Normally the content-type is a configuration of your web server. So I’m sorry if this doesn’t solve your problem, but it worked for me as a simple development server and thought it might help some other people. If you do need correct content-types in the response, you either need to explicitly define them as joeytwiddle has or use a library like Connect that has sensible defaults. The nice thing about this is that it’s simple and self-contained (no dependencies).

But I do feel your issue. So here is the combined solution.

var http = require("http"),
    url = require("url"),
    path = require("path"),
    fs = require("fs")
    port = process.argv[2] || 8888;

http.createServer(function(request, response) {

  var uri = url.parse(request.url).pathname
    , filename = path.join(process.cwd(), uri);

  var contentTypesByExtension = {
    '.html': "text/html",
    '.css':  "text/css",
    '.js':   "text/javascript"
  };

  fs.exists(filename, function(exists) {
    if(!exists) {
      response.writeHead(404, {"Content-Type": "text/plain"});
      response.write("404 Not Found\n");
      response.end();
      return;
    }

    if (fs.statSync(filename).isDirectory()) filename += '/index.html';

    fs.readFile(filename, "binary", function(err, file) {
      if(err) {        
        response.writeHead(500, {"Content-Type": "text/plain"});
        response.write(err + "\n");
        response.end();
        return;
      }

      var headers = {};
      var contentType = contentTypesByExtension[path.extname(filename)];
      if (contentType) headers["Content-Type"] = contentType;
      response.writeHead(200, headers);
      response.write(file, "binary");
      response.end();
    });
  });
}).listen(parseInt(port, 10));

console.log("Static file server running at\n  => http://localhost:" + port + "/\nCTRL + C to shutdown");

Answer 4: Using Node.js as a simple web server

Step1 (inside command prompt [I hope you cd TO YOUR FOLDER]) : npm install express

Step 2: Create a file server.js

var fs = require("fs");
var host = "127.0.0.1";
var port = 1337;
var express = require("express");

var app = express();
app.use(express.static(__dirname + "/public")); //use static files in ROOT/public folder

app.get("/", function(request, response){ //root dir
    response.send("Hello!!");
});

app.listen(port, host);

Please note, you should add WATCH FILE (or use nodemon) too. The above code is only for a simple connection server.

STEP 3: node server.js or nodemon server.js

There is now more easy method if you just want to host a simple HTTP server. npm install -g http-server

and open our directory and type http-server

https://www.npmjs.org/package/http-server

Conclusion:

I hope Using Node.js as a simple web server Solution would be useful for you to learn something new from this solution. If it helped you then don’t forget to bookmark our site for more Quiz Answers and solutions.

Leave a Reply

Your email address will not be published.