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(request, response) {
"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(request, response) {
"use strict";
var uri, filename;
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(filename, function (exists) {
var extension, mimeType, fileStream;
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',
error: function (jqxhr, textStatus, errorThrown) {
console.log('error', textStatus, '//', errorThrown);
},
success: function (json) {
var oldposts;
oldposts = $('#oldposts');
$.each(json.posts, function (i, post) {
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(filename, response) {
"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(pathname, function (exists) {
var extension, mimeType, fileStream;
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 pathname, fileStream;
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(request, response) {
"use strict";
var postText;
postText = '';
console.log('doing add');
request.setEncoding('utf8');
request.addListener('data', function (postDataChunk) {
postText += postDataChunk;
});
request.addListener('end', function () {
var postData, pathname, fileStream;
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(request, response) {
"use strict";
var uri;
uri = url.parse(request.url).pathname;
if (uri === '/fetch') {
fetchMessages(response);
} else if (uri === '/addnew') {
addNewMessage(request, response);
} else if (uri === '/') {
serveFromDisk('forum-base.html', response);
} else {
serveFromDisk(uri, response);
}
}
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() },
error: function (jqxhr, textStatus, errorThrown) {
console.log('error', textStatus, '//', errorThrown);
},
success: function (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 insStmt, i;
insStmt = db.prepare('INSERT INTO posts (name, message) VALUES (?, ?)');
for (i = 0; i < data.length; i += 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(filename, response) {
"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(pathname, function (exists) {
var extension, mimeType, fileStream;
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 (err, row) {
jsonData.posts.push({ name: row.name, message: row.message });
}, function () {
response.write(JSON.stringify(jsonData));
response.end();
});
}
function addNewMessage(request, response) {
"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.name, postData.message, function () {
serveFromDisk('forum-base.html', response);
});
});
}
function processRequest(request, response) {
"use strict";
var uri;
uri = url.parse(request.url).pathname;
if (uri === '/fetch') {
fetchMessages(response);
} else if (uri === '/addnew') {
addNewMessage(request, response);
} else if (uri === '/') {
serveFromDisk('forum-base.html', response);
} else {
serveFromDisk(uri, response);
}
}
http.createServer(processRequest).listen(8888);
console.log('started');