XMLHttpRequests (XHR) can be used to request, receive and send data to the server without reloading the page. It is the main API class in the AJAX construct and it is one of the most important features for modern Websites and Web Applications. But what does AJAX for you, and why do you don’t need jQuery to use it?

Why do you want it?

You may know this “Show more Content” buttons on magazines and blogs, which adds content to the page after a short time you clicked on it. Or this “Rating” and “Like” features especially on Social Media Channels and Networks. The Comment section on FaceBook or YouTube, which adds your content directly after clicking on “Reply” or “Comment”. All this features have one thing in common, they work mainly using AJAX Requests which leads to (inter-) actions without reloading the page itself. I mean it would be horrible if a Video page reloads, just because you comment it while watching.

But AJAX isn’t a feature, which is just based on JavaScript. The Server itself (or mostly the running System on it) needs to be configured and setted up for such requests too. For your understanding: You can describe AJAX Requests with just a normal “call”, which your browser sends to the website you visit too. The server needs to distinguish now between a browser and a AJAX request, because the XMLHttpRequest behind may don’t want to see the default HTML / CSS Template, as you will. Such Systems are called APIs and response mostly in JSON, XML or CSV. But you don’t need to write a “big interface behind” to just add a “+1 Like” function to your blog of course. The server-side programming may be covered in another article, today we’re talking about XMLHttpRequests using JavaScript and just assume a suitable backend!

AJAX in JavaScript

We should write us a small helper function, which takes over the main repeating part of AJAX Requests. It should allow to pass the URL, the HTTP Request Method (GET and POST are the most common ones), some data (if we’re using the POST method) and a working callback handler function. This function will handle the returning content and reply to the user, if necessary.

function ajax(url, type, data, callback){
    var xhttp = new XMLHttpRequest();
    xhttp.onreadystatechange = function(){
        if(this.readyState == 4){
            callback.call(this, this.responseText);
        }
    };
    xhttp.open(type, url, true);
    xhttp.setRequestHeader("Cache-Control", "no-cache");
    xhttp.setRequestHeader("X-Requested-With", "XMLHttpRequest");
    if(type == "POST"){
        xhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
        xhttp.send(data);
    } else {
        xhttp.send();
    }
}

The function above creates a new instance of the XMLHttpRequest prototype, initialize them with some data and attach a main event handler to it. The .open() method sets the Request Method, the respective URL and true as third parameter to force an asynchronous request. This is really important, because you don’t know when the server will answer to your script. If your request isn’t asnyc your script AND your visitor needs to wait until the response comes along, otherwise only your script has to wait.

We also using 3 additional Headers, which will be send to the server too. The “Cache-Control”, “no-cache” string tells our backend system to don’t return a cached result, which is maybe really important for strong dynamic content. The “X-Requested-With”, “XMLHttpRequest” header identifies itself as a AJAX Request. Last but not least: the “Content-type”, “application/x-www-form-urlencoded” informs your server that this is a form submission. Now we just need to call the .send() method, with or without additional data, and wait for the response in our attached Event listener. This small function, which is attached on onreadystatechange, waits for the readyState code 4 which just means “Done” and calls the callback.

jQuery’s method offers more

That is true, jQuery offers 33 options on his jQuery.ajax() method AND also comes along with additional alias functions, which pre-configures some of them. The most options of the main handler just adapts the respective header fields (using the .setRequestHeader() method) or providing callbacks for different events, but ALMOST ALL of them can be handled on your own. Below you’ll find the complete options list.

 

Show jQuery.ajax() Options
accepts
This option just “fills out” the Accept HTTP Header. This header value tells the backend script about the content your JavaScript code will accept. You can simple set this on your own using the following example on the native XMLHttpRequest instance:

.setRequestHeader("Accept", "text/html, application/json")

asnyc
We already talked about asynchronous functions, it’s just the third parameter of the .open() method on our native XMLHttpRequests prototype! I marked this a red, because you should NEVER use non-async calls (on non-local environments), so this option is unimportant.
beforeSend
This is just a callback function, which pass the jqXHR object to allow additional settings on your own. Of course, you can add such a callback function on our helper method too, or you just adapt the functions body and write in what you need directly.
cache
Another option, which just sets and configures the chaching HTTP header value of the respective AJAX Request. We already set this to “no-cache” on our helper method, but you can also easily change this to something what suits your project best!
complete
Just a simple callback function, which gets called after the success / error callbacks. Again: You can add such an easy callback function on your own to our helper function, if you REALLY need it.
contents
This option allows to parse the returning content types, using a regular expression, and pass them into a internal customtype variable. This customtype variable can be used within the converters option to adapt the returning content body to your needs. This is maybe necessary if you don’t know how the server response, or which content type the server uses, or if you want to “answer” with an special content type (on the backend side).

You really don’t need such a function, it’s just a nice feature jQuery offers to adapt as many possibilities as possible. Just parse the responseText in your callback function and handle it on your own.

contentType
As you may see… It’s again just a HTTP Header, which you can configure using this jQuery based option. Our helper function sets this to “application/x-www-form-urlencoded” on POST requests only. jQuery uses the following string, which just adds the respective charset to.

application/x-www-form-urlencoded; charset=UTF-8

context
This option assigns an Element object as this variable on the respective callback functions (like .done() or .complete()). Such a feature can also be done, by adapting the callback call within our helper function.
converters
The converters allows to adapt the returning values by using a “data-type to data-type” key and a respective converter function as value. So you can convert something into plain text, convert JSON objects into the format you need and parse custom types into something more handy.

You really don’t need such a function, it’s just a nice feature jQuery offers to adapt as many possibilities as possible. Just parse the responseText in your callback function and handle it on your own.

crossDomain
Set this option to true to force a crossDomain request (such as JSONP) on the same domain.
data
This is the same as the third parameter on our helper function, with just one single difference. jQuery coverts arrays and objects into respective and valid Query strings, which our helper function doesn’t. Such a feature can be easily added too.
dataType
The expecting data type, which you await from the server. This value doesn’t get passed into the accept HTTP Header, it’s just an important variable for the converters and contents options, to assign and parse the “final” content, which gets passed to the respective callback functions.

You really don’t need such a function, it’s just a nice feature jQuery offers to adapt as many possibilities as possible. Just parse the responseText in your callback function and handle it on your own.

error
Again, a callback function which gets applied, when an error occures, a timeout appears or the server answers with an respective HTTP error status code (so a Status Code between 400 and 500). Our helper function doesn’t “manage” the AJAX response through different callbacks, we just have a single one which is more as enough.
global
This option just enables and disables the global jQuery-own events, such as ajaxStart and ajaxEnd, to get triggered. This isn’t necessary for our helper function, because this event types are jQuery only!
headers
Here you can just define some additional (custom) HTTP headers, which you can also set using XMLHttpRequest natives method .setRequestHeader() on the respective instance.
ifModified
This option allows to configure, if the AJAX request should return successfully or not by checking and syndicate the Last-Modified HTTP header. If the content hasn’t been changed, the request doesn’t end successfully, otherwise it does. (This option is disabled per default, of course.). You can achieve the same, by checking this HTTP Header within your callback function!
isLocal
I’m really not sure but I assume, that this option allows to access the local environment to get some local stored files, for example?
jsonp
jQuerys AJAX function supports also jsonp requests, which work a bit differently than normal requests. This option allows to enable and configure the JSONP request method, next to jsonpCallback.
jsonpCallback
jQuerys AJAX function supports also jsonp requests, which work a bit differently than normal requests. This option allows to enable and configure the JSONP request method, next to jsonp.
method
This is the second argument of our helper function, which allows to set the desired HTTP Request method.
mimeType
This option will overwrite the default mime type provided by the native XMLHttpRequest prototype, which can also be done within your callback function.
password
The .open() method of the native XMLHttpRequest prototype allows five arguments, our current helper function just allows to configure 3 of them. The fifth is the password argument, which is required if you need to identify (or login) yourself on the respective server.
processData
You can set this option to false to disable the parsing of non-string data objects, which is maybe required if you want to send something different then a string. This is a jQuery only function, because it handles the use of the jQuery.param() helper function.
scriptCharset
Here you can configure and adapt the charset of the script tag, which is used on “jsonp”, “script” and “GET” request methods, if the remote script requires another charset type then your document. This is also a jQuery own setting, and cannot be done outside its environment.
statusCode
This option allows to define an object with status codes as key and a respective handler function as value. So it triggers the respective function, when the server response with the respective status code. You can handle this on your own, again, within your own callback function.
success
Another callback function, which gets triggered if the XMLHttpRequest has received an answer successfully. Our helper function doesn’t “manage” the AJAX response through different callbacks, we just have a single one which is more as enough.
timeout
This option sets a timeout in miliseconds, which will break the request (if possible) and return a respective error. This may doesn’t work on each browser, and may contain some buggy behaviors.
traditional
The boolean value on this option just configures the behavior of the jQuery.param() function, which serialize an Array or Object into URL query string. This string gets passed on the respective XMLHttpRequest request.
type
This option just is an alias for method and must be used on jQuery versions prior to 1.9.0!
url
The first parameter of our helper function, which sets the URL which should be called.
username
The .open() method of the native XMLHttpRequest prototype allows five arguments, our current helper function jsut allows to configure 3 of them. The fourth is the username, which is required if you need to identify (or login) yourself on the respective server.
xhr
Here you can define the respective XMLHttpRequest object / prototype, which should be used for the AJAX request. The default is ActiveXObject for Internet Explorer and XMLHttpRequest otherwise.
xhrFields
This option allows to configure the native XMLHttpRequest with additinal keys and values, based within an object. It is maybe necessary if you want to talk with another server, which requires credentials or other additional settings.

Simple Enough?

Is jQuery’s method really easier as just this small helper function? Okay, before you continue using jQuery just for the ajax function check out this AJAX helper function. I try to wrote it similar to jQuerys solution, but I didn’t read the jQuery source, so some functions may behave differently. It also doesn’t support global, ifModified, jsonp, jsonpCallback, mimeType and scriptCharset, but feel free to extend it!

But please don’t get me wrong, this whole DOM and function libraries arn’t bad (ok rather the must of them) and specially jQuery was a really good library, back in 2010. Nowadays, where anyone who uses the Internet Explorer < 11 does it just out of self-hatred and where JavaScript envolves, you don't need jQuery at all. And this Just Vanilla blog post series here on this website should prove that to you!