Node.js Serving HTML pages and Static content

Posted by: Ravi Kiran , on 6/21/2015, in Category Node.js
Views: 108532
Abstract: Serve HTML pages, scripts and styles using Node.js

Node.js is a platform that provides a way to write server side code using JavaScript. This model works well for quickly prototyping a server based application and even in building highly accessed web apps. In our previous post Node.js Tutorial Series - Getting Started, we discussed basics and working model of a Node.js based application. In this post, we will see how to serve HTML pages, scripts and styles using Node.js.

In the previous post, we used the http module to write a hello world application. We will use the same module in this post and will see how it can be used to send different types of responses to the clients.

 

To start with, create a new folder at any location on your system and name it BasicNodeApp. Inside this folder, add an HTML file named index.html and a JavaScript file named server.js. Open the server.js file on your favorite text editor and write the following code in it:

var http = require('http');
var fs = require("fs");

http.createServer(function(request, response) {
}).listen(3000);

The second module in the above snippet (fs) is a built-in module in the platform for accessing file system. Using fs, we can perform CRUD operations over files and directories. It contains both synchronous and asynchronous APIs for talking to the file system. Use of asynchronous API is preferred as it will not block the event loop till the operation is completed.

Let’s add some basic HTML to the index.html page. Open the index.html page in a text editor and paste the following code in it:

<!doctype HTML>
<html>
  <head>
    <title>
      Index
    </title>
  </head>
  <body>
    <h1>
      Hello! Now you know how to serve HTML files using Node.js!!!
    </h1>
  </body>
</html>

Now that we have a simple HTML page, let’s serve this page on every request to the server. Add the following code inside the callback function of createServer method called above:

fs.readFile("index.html", function(err, data){
  response.writeHead(200, {'Content-Type': 'text/html'});
  response.write(data);
  response.end();
});

Now run this application using the following command:

> node server.js

Open a browser and change URL to http://localhost:3000. You will see the HTML render on the screen. The response.writeHead method in the above snippet sets HTTP status code and the content type, based on which the response would be treated by the client.

And the interesting part is, hit any endpoint of the server and you will get the same page. This is something that you definitely don’t want to see. Let’s serve the page index.html only when the endpoint is /index and otherwise, let’s serve some default content. Following code does this:

if(request.url === "/index"){
   fs.readFile("index.html", function (err, data) {
      response.writeHead(200, {'Content-Type': 'text/html'});
      response.write(data);
      response.end();
   });
}
else{
   response.writeHead(200, {'Content-Type': 'text/html'});
   response.write('<b>Hey there!</b><br /><br />This is the default response. Requested URL is: ' + request.url);
   response.end();
}

In the above snippet, we are attempting to read a file but not checking if the operation has failed. The first argument in the callback would contain details of the error if the attempt to read the file has failed. Let’s handle the error and respond with 404 status if the file is not found:

fs.readFile("index.html", function(err, data){
   if(err){
      response.writeHead(404);
      response.write("Not Found!");
   }
   else{
      response.writeHead(200, {'Content-Type': contentType});
      response.write(data);
   }
   response.end();
});

Now, rename the file index.html and run the application. You should see an error displayed on the browser.

Let’s add some basic styling to the page. Create a CSS file and name it myStyles.css. Add a style to change font of the h1 tag used on the page. Add the following CSS to this file:

h1 {
    font-family: cursive;
}

Now modify the server.js file to serve this file whenever it finds a request for the CSS file. Following snippet sends response for the CSS:

if(/^\/[a-zA-Z0-9\/]*.css$/.test(request.url.toString())){
   sendFileContent(response, request.url.toString().substring(1), "text/css");
}

function sendFileContent(response, fileName, contentType){
  fs.readFile(fileName, function(err, data){
    if(err){
      response.writeHead(404);
      response.write("Not Found!");
    }
    else{
      response.writeHead(200, {'Content-Type': contentType});
      response.write(data);
    }
    response.end();
  });
}

Now add a link tag to the HTML file created earlier to point to the CSS file and run the page. The CSS file will load and the styles will be applied on the page.

Similarly, you can respond with a JavaScript file when the server gets a request for it. Check the sample code for an example of it.

Conclusion

Node.js works just like any other server technology and is capable of serving any type of content. The http module used in this post is the low level API for interacting with server in Node.js. We need to have enough knowledge on HTTP status codes and the response types to work on it. Frameworks like Express.js hide this complexity of dealing with this API and provide an easier way to define the server. We will see usage of Express.js in a future post.

Download the entire source code of this article (Github)

Read the next article in this series Using Node.js to build REST APIs

This article has been editorially reviewed by Suprotim Agarwal.

Absolutely Awesome Book on C# and .NET

C# and .NET have been around for a very long time, but their constant growth means there’s always more to learn.

We at DotNetCurry are very excited to announce The Absolutely Awesome Book on C# and .NET. This is a 500 pages concise technical eBook available in PDF, ePub (iPad), and Mobi (Kindle).

Organized around concepts, this Book aims to provide a concise, yet solid foundation in C# and .NET, covering C# 6.0, C# 7.0 and .NET Core, with chapters on the latest .NET Core 3.0, .NET Standard and C# 8.0 (final release) too. Use these concepts to deepen your existing knowledge of C# and .NET, to have a solid grasp of the latest in C# and .NET OR to crack your next .NET Interview.

Click here to Explore the Table of Contents or Download Sample Chapters!

What Others Are Reading!
Was this article worth reading? Share it with fellow developers too. Thanks!
Share on LinkedIn
Share on Google+

Author
Rabi Kiran (a.k.a. Ravi Kiran) is a developer working on Microsoft Technologies at Hyderabad. These days, he is spending his time on JavaScript frameworks like AngularJS, latest updates to JavaScript in ES6 and ES7, Web Components, Node.js and also on several Microsoft technologies including ASP.NET 5, SignalR and C#. He is an active blogger, an author at SitePoint and at DotNetCurry. He is rewarded with Microsoft MVP (Visual Studio and Dev Tools) and DZone MVB awards for his contribution to the community


Page copy protected against web site content infringement 	by Copyscape




Feedback - Leave us some adulation, criticism and everything in between!

Categories

JOIN OUR COMMUNITY

POPULAR ARTICLES

C# .NET BOOK

C# Book for Building Concepts and Interviews

Tags

JQUERY COOKBOOK

jQuery CookBook