Nodejs Book: Chapter 5

So now that we have a basic working file server up and running, if we want
to make a web application, that entails doing more than serving static files.
How can we make requests from a client page and have the server perform some
kind of task relevant to the request.

In the first chapter of this book we established that URL’s are effectively
just a string that is passed into a server and that we had to give it meaning.
One of the meanings that we gave it was that of a file path as we build a file
server. But we can also give URL’s other meanings like calling logic, we just
have to decide on a url-base to distinguish what logic we want executed on the
server.

Basically all we need to do is decide upon a unique URL that doesn’t overwrite
other potential calls to the server. We can decide on “/api”, or “/callback”,
or “/node”, “/rest” or otherwise as long as it doesn’t overwrite a file path.
My personal preference is to use the base of “/api”.

The file layout of this chapter’s code is listed below.

- api.js
+ public/
| - get.html
| - + js/
| --- get.js

File: get.html

<!DOCTYPE HTML>
<html>

    <head>

        <meta charset="utf-8"/>
        <title>Ajax Request</title>

    </head>

    <body>

        <button id="clickBtn">Click Me!</button>
        <p id="responseText"></p>

        <script type="text/javascript" src="js/get.js"></script>

    </body>

</html>

File: js/get.js

"use strict";

var clickBtn = document.getElementById("clickBtn");
var responseText = document.getElementById("responseText");

clickBtn.addEventListener("click", function (event) {

    var xml = new XMLHttpRequest();
    xml.open("GET", "/api/hello", true);
    xml.send();

    xml.onload = function() {

        responseText.textContent = xml.responseText;

    }


});

File: api.js

"use strict";

const http = require("http");
const handleFile = require("handle-file");

const server = http.createServer();
server.on("request", handleRequest);
server.listen(8080, handleListen);

function handleRequest(req, res) {

    switch(req.url) {
        case "/api/hello":

            res.writeHead(200, { "Content-Type" : "text/plain" });
            res.end("Hello, World!");

        break;
        default:

            handleFile(req, res);

        break;
    }

}

function handleListen( ) {

    console.log("Server is listening on port 8080");

}

When we run our server and click on the button we should now see the following
output:

Hopefully the code is in this chapter should be pretty self explanatory, but let’s
take a look at two parts. The first part being the request sent from the client.

var xml = new XMLHttpRequest();
xml.open("GET", "/api/hello", true);
xml.send();

xml.onload = function() {

    responseText.textContent = xml.responseText;

}

While web pages have become much more dynamic, for a long period of time, web pages
were a static fair. A page was served with a list of hyperlinks, and hyperlinks
could be clicked to navigate to another page. It was assumed that any requests to
the server were for a different page. As content on the internet became more dynamic
“Ajax” became a common implementation of sending information to and from the server
from within Javascript.

“Ajax” stands for “Asynchronous JSON and XML” request. And it’s exactly the same
as a browser requesting a page, just performed from within Javascript and without
the page being reloaded. In this case we send a “GET” request to the url “/api/hello”
and once it’s loaded we display the response text to the user.

function handleRequest(req, res) {

    switch(req.url) {
        case "/api/hello":

            res.writeHead(200, { "Content-Type" : "text/plain" });
            res.end("Hello, World!");

        break;
        default:

            handleFile(req, res);

        break;
    }

}

For our server, our api.js only has one minor change from the previous chapter.
We’ve added a switch statement to the request url, giving preference to logical
functions we define and defaulting to serving a file if none of the patterns match.

This was a basic example of testing waters with ajax. And is not very useful yet.
We will continue expanding this example in the next few chapters as we cover sending
and receiving JSON data in the next chapter.