Examples using Node.js

These examples illustrate some simple servers built using Node.js. (These examples are rather old, and in particular they do not use Express, which is widely used today. More modern versions of these examples are also available, split between browser-side code and server-side code.)

Contents:
Example 1: Always serving the same simple page
Example 2: Loading requests from disk
Example 3: Forum using file storage
Example 4: Forum posting via JavaScript
Example 5: Forum using database storage

Example 1: Always serving the same simple page

var http = require('http');
var url = require('url');

function processRequest(requestresponse) {
    "use strict";

    var pathname = url.parse(request.url).pathname;
    console.log('Requested ' + pathname);

    response.writeHead(200, { 'Content-Type''text/html' });
    response.write('<!DOCTYPE html><html lang="en"><head>');
    response.write('<meta charset="utf-8">');
    response.write('<title>' + pathname + '</title>');
    response.write('</head><body>');
    response.write('<h1><tt>' + pathname + '</tt></h1>');
    response.write('</body></html>');
    response.end();
}

http.createServer(processRequest).listen(8888);

Example 2: Loading requests from disk

var http = require('http');
var url = require('url');
var path = require('path');
var fs = require('fs');

var mimeTypes = {'html''text/html''png''image/png',
    'js''text/javascript''css''text/css'};

function processRequest(requestresponse) {
    "use strict";
    var urifilename;
    uri = url.parse(request.url).pathname;
    filename = path.join(process.cwd(), uri);
    // SECURITY HOLE: Check for invalid characters in filename.
    // SECURITY HOLE: Check that this accesses file in CWD's hierarchy.
    path.exists(filenamefunction (exists) {
        var extensionmimeTypefileStream;
        if (exists) {
            extension = path.extname(filename).substr(1);
            mimeType = mimeTypes[extension] || 'application/octet-stream';
            response.writeHead(200, {'Content-Type'mimeType});
            console.log('serving ' + filename + ' as ' + mimeType);

            fileStream = fs.createReadStream(filename);
            fileStream.pipe(response);
        } else {
            console.log('not exists: ' + filename);
            response.writeHead(404, {'Content-Type''text/plain'});
            response.write('404 Not Found\n');
            response.end();
        }
    }); //end path.exists
}

http.createServer(processRequest).listen(8888);

Example 3: Forum using file storage

forum-base.html

<!DOCTYPE html>
<html lang="en"><head>
<meta charset="utf-8">
<title>Forum Example</title>
</head><body>

<h1>Forum Example</h1>

<div id="oldposts"></div>

<h2>Post a New Message</h2>
<form action="addnew" method="post">
Name: <input name="name"></input><br />
<textarea name="message"></textarea><br />
<button type="submit">Post Message</button>
</form>

<script src="jquery-1.7.1.js"></script>
<script src="forum-client.js"></script>
</body></html>

forum-client.js

function fetchPosts() {
    "use strict";
    $.ajax({ url'fetch'dataType'json',
        errorfunction (jqxhrtextStatuserrorThrown) {
            console.log('error'textStatus'//'errorThrown);
        },
        successfunction (json) {
            var oldposts;
            oldposts = $('#oldposts');
            $.each(json.postsfunction (ipost) {
                var add;
                add = $('<div class="post"></div>');
                // SECURITY HOLE: Avoid posting raw HTML from record
                add.html('<b>User:</b> ' + post.name + '<br />\n'
                    + '<div class="message">' + post.message + '</div>');
                oldposts.append(add);
            });
        }});
}

$(document).ready(fetchPosts);

posts.json

"name""Bugs Bunny""message""What's up, doc?" }
,{ "name""Elmer Fudd""message""I'm hunting wabbits!" }
,{ "name""Bugs Bunny""message""What do you mean, a wabbit?" }
,{ "name""Elmer Fudd""message""You know, with big wong ears, and a wittle white fwuffy tail, and he hops awound and awound!" }
,{ "name""Bugs Bunny""message""Listen, Doc. Confidentially, I AM A WABBIT!" }

forum-file-server.js

var http = require('http');
var url = require('url');
var path = require('path');
var fs = require('fs');
var querystring = require('querystring');

var mimeTypes = {'html''text/html''png''image/png',
    'js''text/javascript''css''text/css'};

function serveFromDisk(filenameresponse) {
    "use strict";
    var pathname;
    pathname = path.join(process.cwd(), filename);
    // SECURITY HOLE: Check for invalid characters in filename.
    // SECURITY HOLE: Check that this accesses file in CWD's hierarchy.
    path.exists(pathnamefunction (exists) {
        var extensionmimeTypefileStream;
        if (exists) {
            extension = path.extname(pathname).substr(1);
            mimeType = mimeTypes[extension] || 'application/octet-stream';
            response.writeHead(200, {'Content-Type'mimeType});
            console.log('serving ' + filename + ' as ' + mimeType);

            fileStream = fs.createReadStream(pathname);
            fileStream.pipe(response);
        } else {
            console.log('does not exist: ' + pathname);
            response.writeHead(404, {'Content-Type''text/plain'});
            response.write('404 Not Found\n');
            response.end();
        }
    }); //end path.exists
}

function fetchMessages(response) {
    "use strict";
    var pathnamefileStream;
    console.log('doing fetch');
    pathname = path.join(process.cwd(), 'posts.json');
    response.writeHead(200, {'Content-Type''application/json'});
    response.write('{ "posts": [');
    fileStream = fs.createReadStream(pathname);
    fileStream.addListener('data'function (chunk) {
        response.write(chunk'binary');
    });
    fileStream.addListener('close'function () {
        response.write('] }');
        response.end();
    });
}

function addNewMessage(requestresponse) {
    "use strict";
    var postText;
    postText = '';
    console.log('doing add');
    request.setEncoding('utf8');
    request.addListener('data'function (postDataChunk) {
        postText += postDataChunk;
    });
    request.addListener('end'function () {
        var postDatapathnamefileStream;

        postData = querystring.parse(postText);
        pathname = path.join(process.cwd(), 'posts.json');
        fileStream = fs.createWriteStream(pathname, { flags'a' });
        // SECURITY HOLE: confirm name and message are reasonably short
        // SECURITY HOLE: escape quotes and special chars
        fileStream.write(',{ "name": "' + postData.name
            + '", "message": "' + postData.message + '" }\n');
        fileStream.end();

        serveFromDisk('forum-base.html'response);
    });
}

function processRequest(requestresponse) {
    "use strict";
    var uri;
    uri = url.parse(request.url).pathname;
    if (uri === '/fetch') {
        fetchMessages(response);
    } else if (uri === '/addnew') {
        addNewMessage(requestresponse);
    } else if (uri === '/') {
        serveFromDisk('forum-base.html'response);
    } else {
        serveFromDisk(uriresponse);
    }
}

http.createServer(processRequest).listen(8888);

Example 4: Forum posting via JavaScript

Modify the form element in forum-base.html file to the following:

<form id="addnew">
Name: <input id="name"></input><br />
<textarea id="message"></textarea><br />
<button type="submit">Post Message</button>
</form>

And modify final line of forum-client.js to the following:

$(document).ready(function () {
    fetchPosts();

    $('#addnew').submit(function () {
        $.ajax({ url'addnew'type'post'dataType'json',
            data: { name$('#name').val(), message$('#message').val() },
            errorfunction (jqxhrtextStatuserrorThrown) {
                console.log('error'textStatus'//'errorThrown);
            },
            successfunction (json) {
                fetchPosts();
            }});
    });
});

Example 5: Forum using database storage

forum-db-init.js

var sqlite3 = require('sqlite3');

var db = new sqlite3.Database('posts.db');

var data = [
    ["Bugs Bunny""What's up, doc?"],
    ["Elmer Fudd""I'm hunting wabbits!"],
    ["Bugs Bunny""What do you mean, a wabbit?"],
    ["Elmer Fudd""You know, with big wong ears, and a wittle white fwuffy tail, and he hops awound and awound!"],
    ["Bugs Bunny""Listen, Doc. Confidentially, I AM A WABBIT!"]
];

db.run("CREATE TABLE posts ( name TEXT, message TEXT )"function () {
    "use strict";
    var insStmti;

    insStmt = db.prepare('INSERT INTO posts (name, message) VALUES (?, ?)');
    for (i = 0i < data.lengthi += 1) {
        insStmt.run(data[i]);
    }
    insStmt.finalize();
});

forum-db-server.js

var http = require('http');
var url = require('url');
var path = require('path');
var fs = require('fs');
var querystring = require('querystring');
var sqlite3 = require('sqlite3');

var db = new sqlite3.Database('posts.db');
var dbSelectStmt = db.prepare('SELECT name, message FROM posts');
var dbInsertStmt = db.prepare('INSERT INTO posts (name, message) VALUES (?, ?)');

var mimeTypes = {'html''text/html''png''image/png',
    'js''text/javascript''css''text/css'};

function serveFromDisk(filenameresponse) {
    "use strict";
    var pathname;
    pathname = path.join(process.cwd(), filename);
    // SECURITY HOLE: Check for invalid characters in filename.
    // SECURITY HOLE: Check that this accesses file in CWD's hierarchy.
    path.exists(pathnamefunction (exists) {
        var extensionmimeTypefileStream;
        if (exists) {
            extension = path.extname(pathname).substr(1);
            mimeType = mimeTypes[extension] || 'application/octet-stream';
            response.writeHead(200, {'Content-Type'mimeType});
            console.log('serving ' + filename + ' as ' + mimeType);

            fileStream = fs.createReadStream(pathname);
            fileStream.pipe(response);
        } else {
            console.log('does not exist: ' + pathname);
            response.writeHead(404, {'Content-Type''text/plain'});
            response.write('404 Not Found\n');
            response.end();
        }
    }); //end path.exists
}

function fetchMessages(response) {
    "use strict";
    var jsonData;
    console.log('doing fetch');
    response.writeHead(200, {'Content-Type''application/json'});
    jsonData = { posts: [] };
    dbSelectStmt.each(function (errrow) {
        jsonData.posts.push({ namerow.namemessagerow.message });
    }, function () {
        response.write(JSON.stringify(jsonData));
        response.end();
    });
}

function addNewMessage(requestresponse) {
    "use strict";
    var postText = '';
    console.log('doing add');
    request.setEncoding('utf8');
    request.addListener('data'function (postDataChunk) {
        postText += postDataChunk;
    });
    request.addListener('end'function () {
        // SECURITY HOLE: confirm name and message are reasonably short
        var postData = querystring.parse(postText);
        dbInsertStmt.run(postData.namepostData.messagefunction () {
            serveFromDisk('forum-base.html'response);
        });
    });
}

function processRequest(requestresponse) {
    "use strict";
    var uri;
    uri = url.parse(request.url).pathname;
    if (uri === '/fetch') {
        fetchMessages(response);
    } else if (uri === '/addnew') {
        addNewMessage(requestresponse);
    } else if (uri === '/') {
        serveFromDisk('forum-base.html'response);
    } else {
        serveFromDisk(uriresponse);
    }
}

http.createServer(processRequest).listen(8888);
console.log('started');