Introduction

Recall from the AJAX States chapter, the fact that AJAX requests are just plain HTTP requests sent via a different mechanism from the browser. They are first composed, then sent to the server, which reads them, understands them and finally throws out a response in return.

Further exploring the part where the request is composed we see that there are different methods of requesting data from the server. The one we've been using so far is GET, which in simple words, instructs the server to get a given file.

Although it can fulfill many purposes, a plain GET request is not always useful for the end application. Sometimes we need to send some data to the server as well, post large files or just call on the response headers of a file.

As you'll see in this chapter there are dedicated HTTP methods to accomplish some of these tasks more efficiently and more securely. Specifically we'll be discovering GET requests appended with query strings, POST requests and finally ending on with HEAD requests.

Just GET it

Let's start off this list by considering the most basic HTTP request method i.e GET.

The GET method literally asks a server to get a file and return it.

It is the method used to request for a webpage each time we click on a link, or enter its URL into the browser's address bar. When appended with a query string, it can also serve to carry on data in the request. This data can then be read by the server and used to tailor the response.

Following is the general form of a query string: ?name1=value&name2=value

It begins with a question mark ? followed by the name-value pairs of the data. Each pair is separated by an ampersand & and within the pair the assignment to the value is done using an equals sign =.

Spaces are enemies inside a query string - there can be no spaces between anything apart from the actual values (or the parameter names) where they must be encoded.

We'll see more on encoding later in this chapter.

Once formed, a query string can be appended to a URL as shown in the general form below:

http://www.example.com/?name1=value&name2=value
http://www.example.com/page1.php?name1=value&name2=value

Let's consider a very simple example. We send a GET request to a file welcome.php along with the query string ?msg=Hello. The server script at the back-end parses this query string and outputs the value of msg which we finally write to the document.

var xhr = new XMLHttpRequest();

// notice the query string below
xhr.open("GET", "welcome.php?msg=Hello", true);

xhr.onload = function() {
    if (this.status == 200) {
        document.write(this.responseText);
    }
}

xhr.send()
welcome.php
<?php
    echo $_GET["msg"];
?>
In this example we've used one of the newer events of XMLHttpRequest() object i.e onload. You can take a refresher at AJAX Events.

Run this code in your browser, and you'll get the expected response - "Hello".

Live Example

Although this example works perfectly, it misses the conventional welcome string i.e "Hello World".

Following we set msg, in the query string, in a such a way that the server script outputs it as "Hello World".

var xhr = new XMLHttpRequest();

// notice the query string below
xhr.open("GET", "welcome.php?msg=Hello%20World", true);

// rest of the above same as above

Notice the query string ?msg=Hello%20World and within it the strange set of characters - %20. This is an instance of a concept known as character encoding.

Encoding refers to the conversion of non ASCII, special and unsupported characters into hexadecimal values prefixed by a percent sign, that can be sent safely over the network and decoded easily by the server.

In this example, the space is an invalid character inside the value "Hello World" and hence must be encoded into some permutation of characters before being sent in the request.

A space encodes to the value %20 (since its character code in decimal representation is 32 which is 20 in hexadecimal representation). Different characters get encoded to different codes as shown in the table below.

CharacterCharacter codeEncoded value
Space32%20
?63%3f
!33%21
"34%22
'39%27
.46%2e

Fortunately you don't need to remember these codes to be able to produce safe query string values. Thanks to the function encodeURIComponent().

The global function encodeURIComponent() takes a string argument and returns its encoded version - thus making it ready to be transmitted as a URL parameter value. We can use this function in AJAX applications to encode query string values on the go and concatenate them into the actual string.

However note that while doing so you have to encode actual values only; not the whole query string because otherwise doing so will encode the ?, = and & characters as well and consequently produce an invalid query string.

Following is an example illustrating this whole discussion:

var xhr = new XMLHttpRequest();

// encode "Hello World" and save it in encodedMsg
var encodedMsg = encodeURIComponent("Hello World");

xhr.open("GET", "welcome.php?msg=" + encodedMsg, true);

// rest of the above same as above

As you can see here, we only pass the actual value "Hello World" to encodeURIComponent(); not the whole query string; and then append the encoded value to the query string.

Live Example

GET requests are common when one simply wants to retrieve a file or provide it short amounts of non-sensitive data. Talking specifically about parameterised GET requests, often you'll find these in widgets for filtering data in web applications.

For example suppose you're on an online store and want to see only those items that are within $100 of price - the webpage can provide a checkbox to implement this functionality by sending a GET request on its click with let's say the query string ?price=100.

However GET isn't always the method that meets all our needs. Sometimes we need other methods in place of it for sending our request with more flexibility such as POST; as we explore next.

Posting data

Besides GET, another pretty common request method out there is the method POST.

A POST request operates similar to a GET request, except for the fact that it is meant to send data to a server. Apart from the request headers, POST also sends out a request body which holds the data.

POST is commonly used to send sensitive information such as passwords in the request or to send files and large chunks of data. We'll discover a lot more to it in the next chapter.

Sending a POST request in AJAX isn't anything of a surprise. We've to obviously start by setting the first argument of open() to "POST". This establishes the method for sending the AJAX request.

After this we've to work on sending data in the request; otherwise there's no point of posting it. To do this we simply construct the same syntactical name-value pairs as we did for GET in the examples above, but this time instead of appending them to the URL, we supply them to send() as a single string argument.

The method will take the string argument given to it and simply add it to the body of the request, thus completing the to-do list for POST.

But this isn't all to it - there are three formats of sending a POST request to a server, given by the Content-Type header. They are:

  1. application/x-www-form-urlencoded
  2. multipart/form-data
  3. text/plain

The first type, application/x-www-form-urlencoded, is the default when posting data to a server using an HTML form with method="POST". It tells the server that the body of the request is in encoded form, which can then easily decode and parse the different pairs.

The second type, multipart/form-data, is mostly used to send file data in the request. It means that the name-value pairs of the data have been broken down into individual parts and structured out, each on a separate line with a corresponding boundary set within Content-Type.

The third and last type, text/plain trivially sends out the data as is in the request. It's least used, but nonetheless one of the ways to POST data to a server and process it right there.

We'll understand each of these types in detail in the next chapter.

The setRequestHeader() method

Since all these cases involves setting up a request header, now it's the high time to tell you the way to do so. The method setRequestHeader(), as the name suggests, sets a header for a given request. It takes two arguments: first the name of the header and second, its name, both as strings.

You might get expected results from the server-end if you forget setting the Content-Type request header to the value application/x-www-form-urlencoded or multipart/form-data!

Consider the following example.

var xhr = new XMLHttpRequest();
xhr.open("POST", "welcome.php", true);
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");

xhr.onload = function() {
    if (this.status == 200) {
        alert(this.responseText);
    }
}

xhr.send("msg=Hello");

We send a POST request to a file post-welcome.php along with some data, and Content-Type set as application/x-www-form-urlencoded. The file at the backend parses the data and finally returns it.

post-welcome.php
<?php
    echo $_POST["msg"];
?>

Live Example

Headers only

In addition to the old GET and POST request methods, new ones have sprung up in recent times. HEAD is one of these candidates and perhaps a very useful request method.

HEAD instructs the server to only send headers for the request received. This is where the method gets its name from i.e HEAD for headers.

Following we dispatch a HEAD request to check for the Content-Type of a given file:

var xhr = new XMLHttpRequest();
xhr.open("HEAD", "foods.html", true);

xhr.onload = function() {
    if (this.status == 200) {
        alert("Content-Type: " + this.getResponseHeader("Content-Type"));
    }
}

xhr.send();

Once the request is complete, we alert the Content-Type of the response by calling the getResponseHeader() method.

Live Example

Try requesting for different types of files and see the alert made in each case.
To learn more about the getResponseHeader() method go to the AJAX Response Headers chapter.

You're part of a team of developers which is working on a new web service. You have taken the job of working on the client-end AJAX coding, because you know the technique well enough!

Now you're given the task to write some code from scratch, to check whether a given file on the server is lesser than 10MB or not. If it's lesser, you shall log "OK", otherwise "Sorry".

For simplicity, suppose that the following function serves to carry out this check, with an argument filepath that's the whole path of the file to check for.

function checkSize(filepath) {
    // write your code here
}

Using the most appropriate request method, write some code to accomplish the aforementioned task, in the body of checkSize().

The size of the file is provided by the server in the Content-Length response header, in units of bytes.

There is no need to call on the whole file - just the headers will do the job too!

function checkSize(filepath) {
    var size = 0;
    var xhr = new XMLHttpRequest();
    xhr.open("HEAD", filepath, true);

    xhr.onreadystatechange = function() {
        if (this.readyState === 4 && this.status === 200) {
            size = Number(this.getResponseHeader("Content-Length")) / 1000 / 1000;
            if (size <= 10) console.log("OK");
            else console.log("Sorry");
        }
    }

    xhr.send();
}

In conclusion

AJAX is a powerful driving force behing intuitive, interactive and dynamic application and understanding its inner workings is of utter importance for developers and front-end engineers who want to smoothly work with it.

Part of this involves understanding the different methods of sending out requests and the purpose of each of them. There is no doubt in the fact that one must be perfect with HTTP requests in order to be perfect with AJAX. At the end it all boils down to sending and handling HTTP requests manually!