OK, enough “Hello World!” Let’s serve up an HTML file, dagnabbit.
In Part I of this series: “Making a Simple HTTP Server with Node.js – Part I“, we learned the bare-bones steps needed to create an HTTP server with Node.js. While it was fun to see our text message make its way from our server-side JavaScript file, at the end of the day we sent a hard-coded text message. Not too sexy.
In this article, we will invite the user to type “index.html” into their browser window and prepare to be amazed. Ok, the user has to be on your local DEV machine, and type “http://localhost:3000/index.html”, but we have to start somewhere, right?
Example # 1
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 |
//step 1) require the modules we need var http = require('http'),//helps with http methods path = require('path'),//helps with file paths fs = require('fs');//helps with file system tasks //a helper function to handle HTTP requests function requestHandler(req, res) { var content = '', fileName = path.basename(req.url),//the file that was requested localFolder = __dirname + '/public/';//where our public files are located //NOTE: __dirname returns the root folder that //this javascript file is in. if(fileName === 'index.html'){//if index.html was requested... content = localFolder + fileName;//setup the file name to be returned //reads the file referenced by 'content' //and then calls the anonymous function we pass in fs.readFile(content,function(err,contents){ //if the fileRead was successful... if(!err){ //send the contents of index.html //and then close the request res.end(contents); } else { //otherwise, let us inspect the eror //in the console console.dir(err); }; }); } else { //if the file was not found, set a 404 header... res.writeHead(404, {'Content-Type': 'text/html'}); //send a custom 'file not found' message //and then close the request res.end('<h1>Sorry, the page you are looking for cannot be found.</h1>'); }; }; //step 2) create the server http.createServer(requestHandler) //step 3) listen for an HTTP request on port 3000 .listen(3000); |
There are a few new things happening in Example # 1, when compared to the examples from Part I of this series. The biggest change is that we’ve expanded “Step # 1” and are requiring two new Node.js modules: “path” and “fs”.
The “path” module provides a number of methods that help you to examine and parse file paths. The “fs” module is short for “File System”. This module provides access to the file system. So here is where the fun stuff starts: Writing JavaScript that has access to the local file system? Yep. You bet. We have not even begun to scratch the surface of what is possible.
Next, our helper function has grown a bit as well. We use the basename() method of the path module to return the name of the file that was requested by the user (i.e. index.html). We then leverage the “__dirname” keyword, which provides a quick and easy handle to the folder that your server-side JavaScript file resides in.
After that, we check to see if the user has requested “index.html”, and if so we will return it. The fs.fileRead() method takes two arguments: a path to the physical file that we want to return to the user, and an anonymous function. That anonymous function takes two arguments: an error object, and the content of the file that is to be returned. So just to play it safe, we check to see if there is an error: if ( !err ). If there is none, then we use the res.end() method to return the contents of index.html and then close the request. If there was an error, for now we are piping it to the console for our own troubleshooting.
If none of that worked out, then we set a “404 / Not Found” header, and send some markup back, letting the user know. Step # 2 and Step # 3 haven’t changed since our last article: Create the server, and then listen for a request.
Phew!
That was a lot, but our Node.js HTTP server has grown up quite a bit. Instead of just sending back a plain text message or some hard-coded HTML, we are now serving up an actual HTML file. We could change that file any time, which would change what the user sees in the browser. It’s not exactly Facebook, but hey, we are creating an HTTP web server using nothing but JavaScript!
For Part III, we will smarten things up and enhance our server so that it will serve up any static content that is requested.
Summary
In this article we learned how to use the “path” and “file system” Node.js modules. By leveraging the modules, we were able to read the path of the HTTP request, and read from the file system. We also learned about the “__dirname” keyword.
Helpful Links for the Node.js path and fs Modules
http://nodejs.org/api/path.html
http://docs.nodejitsu.com/articles/file-system/how-to-use-the-path-module
http://jspro.com/nodejs/accessing-the-file-system-in-node-js/
http://docs.nodejitsu.com/articles/file-system/how-to-read-files-in-nodejs
[…] Part II of this series we learned how to use the “path” and “file system” modules. By leveraging these Node.js […]
[…] from http://blog.kevinchisholm.com/javascript/node-js/making-a-simple-http-server-with-node-js-part-ii/ […]