Creating a HTTP server to serve up HTML and image files using Node.js.
Setting up a small HTTP web server can be a lot of hassle if you’re using a ‘proper’ server such as Apache or Nginx. The alternative is to code a simple server yourself that can carry out basic functions.
Our goal is to create a program that can receive HTTP requests and serve up HTML pages and images. To keep it simple, we’re not going to worry about other files such as audio or video. Also, we won’t even think about SSL encryption and HTTPS.
You can get the code from this blog as well as the examples I used to test it from GitHub here.
Writing code to serve html
Firstly, we use
require to import the http module, which we use to accept HTTP requests, and the fs (filesystem) module, which we’ll use to read files.
We then use the http module to create a server on port 80, and give it the function
request_handler to be run when it receives a request.
We then declare the function
request_handler which accepts two arguments – the request and its details, and the response which it can use to send data back. We use the variable
page to store the name, or location, of the file that has been requested.
request.url is the url the user has asked for, such as ‘/index.html’.
.slice(1) is then used to chop off the ‘/’ at the start so that only the file’s location is left. If the user hasn’t specified a page, we assume that they want ‘index.html’, which is the standard name for a home page. Finally, fileType is set to an array of the file’s location split at the ‘.’, such as [‘index’,’html’]. We then set it to the last item in the array to get the file type (‘html’).
We then print the IP address of the person who has connected and the URL they requested to the console. Next we use
fs.readFile to get the data in the file that has been requested,
readFile is asynchronous. This means that the program will not wait for it to finish – it will continue to execute the next line of code while
readfile is running. Since it will take the operating system some time to find the file and return its contents, we cannot simply add the code to send the contents on the next line. We must use a callback. This is a function that is passed as an argument to
readFile, which it will execute after it has finished. By doing this, we can create a function to send the contents which will automatically be called when the file’s contents have been retrieved. The function will also have two arguments passed to it – ‘err’, which contains any errors that have happened, and ‘data’, which is the contents of the file.
Inside the callback function we check whether there was an error reading the file. If there was, we assume the file doesn’t exist and set the response’s status code to 404, which is a standard code that indicates the server was unable to find what the client requested.
If there was no error, we send a header to tell the client’s browser that
If there was no error, we send a header to tell the client’s browser the server is sending HTML code. We then send the data before ending the response. We then end the callback function and the
request_handler function. Here’s all the code together:
Testing with HTML files
Before we can test our code, we need to create a HTML file for it to serve up. Create a file called ‘index.html’ in the same directory as server.js and write some html such as:
Once you’ve installed Node.js you can open command prompt (for Windows) and type in ‘cd’ followed by the directory your .js file is located in. Then you can type in ‘node server.js’ to run your file.
Open a browser and go to http://127.0.0.1. You should see your html page displayed on your screen. It works! However, there’s one problem – images. If you try and add an image to your HTML file or request an image in the URL it doesn’t work – the image file doesn’t display. We need to add some more code to serve images.
Adding code to serve images
As you can see, we’ve added an ‘else if’ statement that checks if the client has requested a PNG, JPG or GIF image file. If they have, it tells the browser that the server is sending an image with the Content-Type header. Also, we have to encode the data that’s sent as binary, rather than the default, UTF-8, which only works for text. Here’s the new code:
Testing with images
You can get this code, and the examples I’m about to use, on GitHub here.
To test the the server with images, we’re going to create a folder called ‘images’, and add an example GIF and JPG file. Now, if you run the server again, you should be able to request these images from the browser. Go to http://127.0.0.1/images/sample-JPG.jpg and you should be greeted by a nice image. You can also add images in HTML files. For example, you can modify your index.html file like so:
Now, when you go to http://127.0.0.1/, you should be greeted by a GIF image below the ‘Hello World!’ message:
And that’s it! Now you can serve html and image files from your own basic server without having to install anything like Apache. Enjoy!