How to use AJAX with JSON and without jQuery

Programming with BosseI’d like to begin by explaining the “without jQuery” part of the title; jQuery is a really neat JavaScript library. It very useful, for example when using AJAX, and very, very common. So why not use it here, then? Well, I have two major problems with jQuery: 1) I am a programmer who actually enjoys programming, and I want to learn and get good at the programming languages that I use. Using the “macro” shortcuts that jQuery provides instead of actually writing a (JavaScript) program to do the job doesn’t really work for me. And, 2) for different reasons, I cannot use jQuery at work.

AJAX is a method and set of techniques for creating asynchronous web applications. Sounds a bit vague, you say? Well, it’s difficult to explain in just a few words. Let’s try it this way; Consider the “levels” of web pages that you might visit daily:

  • A static web page doesn’t change unless someone alters the source for it. This is typically a “pure” HTML document.
  • The contents of a dynamic web page is determined when the document is requested from (and generated by) the web server. This can, for example, be done using specialized languages like PHP or ASP, or by practically any language through CGI (Common Gateway Interface).

In both cases, once the web page has been loaded to the viewer’s web browser, it doesn’t change (though it can contain client-side code to, for example, let the viewer hide or show different sections of the page). If you want to create a web page where the contents can actually change without forcing the web browser to reload the document from the server, you will need to use a technique like AJAX to do it.

Still vague? OK, an example then – one that you probably use many times a day; Google Search (or whatever flavor of search engine you prefer – I like Google myself).

When you start typing characters in the Google Search text field, a drop-down list will appear below the text field to display the five(-ish) most likely ways to complete the search criteria you have started to type. Have you thought about where this information comes from? Has your web browser downloaded the absolutely massive database from the Google servers? Of course not. As you keep typing, the web page continually uses AJAX queries to send the current text to the Google search engine, which returns the list of suitable “completions” to display.

I started this blog post with the intention of including a working example of using AJAX in a similar way as above to search entries in a phone-book database. However, as the post grew, I had more and more problems with editing it, so finally I lifted the example to a separate entry: AJAX example: The phone-book

How it works

AJAX stands for “Asynchronous JavaScript and XML”, though that description is not entirely accurate.

Asynchronous” requests (which here means to send the request and use an event handler to take care of the response whenever you get it, instead of freezing the application while waiting for the response) makes sense in a web application where you don’t know how long it will take to get the response, but you are not forced to do it that way. It can be very frustrating for a user when a delayed response suddenly updates (for example) a list of data that he is currently trying to select an item in. My AJAX applications typically use a mix of synchronous and asynchronous requests, depending on the task to be performed.

XML” refers to the format of the data passed between the server and client (the web browser). Using XML is usually a good choice, but you don’t need to do that either. I prefer to use the JSON (JavaScript Object Notation) format in most cases, so that is what we’ll do here.

To initiate an AJAX request, you first create (from JavaScript in the client) an XML HTTP object. You specify things like whether you want the request to be synchronous or asynchronous, whether it should use the GET or POST method, the URL to send the request to, etc, and then you invoke its Send method.

If the request is synchronous, you will get the response directly from the Send invocation (or to be more precise, the Send invocation will not return until the response have been received from the server). If the request is asynchronous, the Send invocation will return immediately, and the response (and any status updates) will trigger events that are handled by the event handler that you specified when creating the request object.

The components of an AJAX application

I feel that I should repeat that you don’t need to use JSON for both request and response data (or at all). The way I see it though, this is a solution that will work for virtually any task, and it is really no more complicated than, say, using the GET method and just pass a parameter string. So I’ll keep promoting the JSON way.

Client side JavaScript

In the sub sections below, we use the XMLHttpRequest class to instantiate the XML HTTP object that we need to perform the AJAX request. This works with all common web browsers except MSIE browsers older than version 7. If you want to make sure that your JavaScript works for older MSIE browsers, you can do something like this:

About using JSON in JavaScript: We will be using the stringify and parse methods of the common JSON class to encode and decode the JSON data. There is a potential problem here in that the JSON class may not be available in older web browsers.

To make sure that the JavaScript code will work on any browser, you can for example use json2.js. This JavaScript will add a JSON class with stringify and parse methods if it does not already exist. You can download it and put it on your website, but it’s simpler to just link to it on a CDN (Content Delevery Network), for example cdnjs, by adding a line like this in the HEAD section of your HTML code:

An asynchronous request

An asynchronous request means that when you send the request, you also assign an event handler to it for the readyStateChange event. Your JavaScript code can then continue to do other stuff while the server processes the request, and when the server sends the response, it will invoke your event handler.

Create the XML HTML object to use for the request:

Now attach the event handler function, here named myAjaxResponseHandler, that you have created (see further down).

We want to pass the XML HTTP request object to the event handler as a parameter rather than declaring it as a global variable, mainly because a global variable could only be used for one request at a time – this way we are not limited in how many simultaneous requests we might want to juggle. Passing parameters to an event handler is however a bit tricky in JavaScript, so we end up with this rather un-intuitive piece of code. What we do is to attach an anonymous function to the event, which in turn will invoke our own event handler and pass it the request object (httpRegObj) as parameter. The e parameter is the event object itself.

The reason that I use the call method above instead of invoking myAjaxResponseHandler directly, is that this piece of code is typically inside a generic “send-an-AJAX-request” function, and what I here called myAjaxResponseHandler is not the actual event handler function, but rather the name of the parameter through which the event handler is passed to this function.

Open the request. “POST” is the method that we want to use, <<url>> should be replaced with the URL of the PHP script (or similar) that the request is to be sent to, and “true” means that this will be an asynchronous request (false would make it synchronous).

Assign a header that indicates that we will be sending data on JSON format with the request.

And finally, send the request by invoking the Send method. The parameter to the Send method should be the request data encoded as JSON string. The invocation below assumes that the requestData variable is something that can be encoded to a JSON string, so I included an example assignment (a simple JSON object) for clarification.

Earlier, we added a handler for the readyStateChange event of the request. This is what the frame for that function could look like:

You might have noticed that this function only takes a single parameter, while the invocation of it from the anonymous function that we attached as event handler earlier sends two parameters. That’s because the first of those parameters was the event object itself, and within this function that object can be accessed directly as this (if you should need it).

The event that will invoke this function is the readyStateChange event. readyState is also an attribute of the request object, meaning that in the function, we can examine it as httpReq.readyState. This integer attribute will typically change through the whole sequence of 0 to 4, and this function will be called on each change:

  1. Request not initialized.
  2. Request has been set up.
  3. Request has been sent.
  4. Request is being processed.
  5. Request is complete.

Though you might want to use the other states for updating a status field or something, typically you will only be interested in handling the final state, 4, which is when you will get the results.

The second attribute that we look at in the function, httpReq.status, is an integer attribute. Note that this is only defined when the request is completed, that is when httpReq.readyState is 4. Status 200 means that the request was successful and that the result is available, so when we have seen that this is the case, we can decode the returned JSON data with:

And that is the end of the AJAX request. Now you just have to deal with the data that you got from the server.

A synchronous request

A synchronous request is where the JavaScript code will “freeze” until it has received the final response from the server.

What you need do here is pretty much the same as for the asynchronous request described in the previous section – the difference being that there is no need for an event handler. So I’ll just condense it into a short example snippet – see above for additional explanations.

Note that the third parameter to the open method above is false (true for asynchronous requests). Also, testing for readyState == 4 is probably not necessary for a synchronous request, but better to be safe than sorry.

Server side PHP

We are POSTing our requests from the client as JSON data, which means that in the PHP script that receives the requests, the JSON data will be encoded in the global variable $HTTP_RAW_POST_DATA. To decode the JSON data into the $req_data variable (or whatever you want to call it) as “mixed” PHP format, we can do this:

Setting the second parameter to json_decode() to true as above, means that any JSON objects in the data will be decoded as associative arrays (a set of key/value pairs) instead of actual PHP objects.

For example the “dummy” JSON data that I used for the requests in the two previous sections was a single JSON object (denoted by the curly brackets) containing a single JSON pair with the key cmd and the value “do something”:

When the server receives this data and decodes it using the code line above, the JSON object will turned into an associative array with one element that you can access like this (for example):

The response data for the request will be the “document” generated by the PHP script, meaning that anything you want to return to the caller should just be echo:ed from code. Remember that our client expects the response to be a JSON string, so anything that you echo from the script will need to be JSON encoded.

I prefer to do this by having just one single echo statement in the whole script, and that is on the very last line of the script:

$response_arr is a global array that I usually create on the first line of the script, and everything that should be returned from the script is added to that array:

Above, I create the array and initializes it to indicate an unspecified error. Later on, the status and message fields can and will be updated to indicate success or possibly a more specific failure. Like:

Or:

And that is all there is to it.


Comments

How to use AJAX with JSON and without jQuery — 1 Comment

  1. Pingback: AJAX example: The phone-book | iseborn.eu

Add Comment Register



Leave a Reply

Your email address will not be published.

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code class="" title="" data-url=""> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre class="" title="" data-url=""> <span class="" title="" data-url="">