How to Make AJAX Requests With Raw Javascript
    videos

How to Make AJAX Requests With Raw Javascript

Javascript frameworks have turned simple AJAX functions into one-liners. This is quite incredible, considering the fact that it would require more than twenty to accomplish the same thing with raw Javascript. Nevertheless, it’s important to learn what’s “under the hood”.

Screencast

Get Request

Final Script

This is a relatively simple script that will allow you to asynchronously request pages by using a “load(URL, CALLBACK)” function.

// Our simplified "load" function accepts a URL and CALLBACK parameter.
load('test.txt', function(xhr) {
	document.getElementById('container').innerHTML = xhr.responseText;
});

function load(url, callback) {
		var xhr;

		if(typeof XMLHttpRequest !== 'undefined') xhr = new XMLHttpRequest();
		else {
			var versions = ["MSXML2.XmlHttp.5.0",
			 				"MSXML2.XmlHttp.4.0",
			 			    "MSXML2.XmlHttp.3.0",
			 			    "MSXML2.XmlHttp.2.0",
			 				"Microsoft.XmlHttp"]

			 for(var i = 0, len = versions.length; i < len; i++) {
			 	try {
			 		xhr = new ActiveXObject(versions[i]);
			 		break;
			 	}
			 	catch(e){}
			 } // end for
		}

		xhr.onreadystatechange = ensureReadiness;

		function ensureReadiness() {
			if(xhr.readyState < 4) {
				return;
			}

			if(xhr.status !== 200) {
				return;
			}

			// all is well
			if(xhr.readyState === 4) {
				callback(xhr);
			}
		}

		xhr.open('GET', url, true);
		xhr.send('');
	}

// or with jQuery...
$('#container').load('test.txt');
Object Properties

A Few Notes To Consider While Watching

onreadystatechange will fire five times as your specified page is requested.

  • 0: uninitialized
  • 1: loading
  • 2: loaded
  • 3: interactive
  • 4: complete

A value of "4" is what we're searching for. Once it's been reached, we know that we're free to perform an action with the returned data.

XMLHttpRequest and ActiveXObject

Modern browsers utilize the "XMLHttpRequest" object to make asynchronous requests. That means, if you'd like to ignore IE6, you're free to remove the ActiveXObject check - this section.

		if(typeof XMLHttpRequest !== 'undefined') xhr = new XMLHttpRequest();
		else {
			var versions = ["Microsoft.XmlHttp",
			 				"MSXML2.XmlHttp",
			 			    "MSXML2.XmlHttp.3.0",
			 			    "MSXML2.XmlHttp.4.0",
			 			    "MSXML2.XmlHttp.5.0"];

			 for(var i = 0, len = versions.length; i < len; i++) {
			 	try {
			 		xhr = new ActiveXObject(versions[i]);
			 		break;
			 	}
			 	catch(e){}
			 } // end for
		}

Instead, you could just write "var xhr = new XMLHttpRequest();". Be cautious with this method. Once abstracted to its own "load" function, it's easy to keep the IE check as it is.

Get Out of the Global Space

If making multiple requests, you might consider moving your code into its own object. Then, rather than directly calling the "load" function, you use "myObject.load();". A basic guideline to accomplishing this would be:

var ajax = {
   load : function() {
// paste here
   },

   otherMethod : someFunction() {
// paste here
   }
}

ajax.load();

Conclusion

I've no doubt that some of you will leave a comment stating something along the lines of, "Why would I ever do this when it can be done with just one line of jQuery?" The answer is because you need to learn what's under the hood of your car, so to speak. Frameworks like Mootools and jQuery have made Javascript unbelievably accessible to designers. If you fall into this category, I strongly recommend that you pick up a raw Javascript book as well. There's nothing wrong, in my opinion, with learning both simultaneously. Just be sure that you do learn both!


It's similar to working with WordPress if you don't know PHP. Sure, it's possible - but would you really want to?

Hopefully, this should get you up and running! I'd love to hear your thoughts! Have a great weekend. See you on Monday, or on Twitter!

  • Subscribe to the NETTUTS RSS Feed for more daily web development tuts and articles.


Add Comment

Discussion 56 Comments

  1. Robert DeBoer says:

    Thank you so much Jeff, this is invaluable. You makes learning things so easy.

    I am a perfect example of why it is important, and sometimes a must, to know the workings of things. I have followed all the JQuery for Beginners tutorials, and so I am pretty sure I could do some awesome things with JavaScript via the JQuery library.

    However, I have just started working for another web development company, and the owner wants all of the code to be 100% ours – no third party, no matter what the license. So a weekend or two ago I am pulling my hair out trying to figure out AJAX request with my own JavaScript code. Yes, I could do it in JQuery, and easy, but company policy prohibited it. So now I am going to have to do all the the sweet JavaScript things JQuery and other JavaScript libraries do, but from scratch on my own – meaning building my own JavaScript framework/library. Thanks again!! This is perfect timing.

    • “Yes, I could do it in JQuery, and easy, but company policy prohibited it.”

      That’s 100% ridiculous to me.

      • Scott says:

        Yeah, I could see the merits of being able to say everything you code is 100% yours but I don’t see the benefits of that outweighing the benefits of finishing projects much quicker and more efficiently.

      • Shane says:

        100%, yes. Time to move company.

      • Jeremy says:

        I’ll take my code over any JavaScript library any day.

      • Tyrel Kelsey says:

        Why would you load an entire library to do such simple things as AJAX. have libraries made us that lazy

      • Isaac Seymour says:

        Come on, the size jQuery is hardly significant in the days of 2Mb/sec being considered slow. 19KB? Nearly 3 seconds on old dial-up, but hardly a blip now. And can you honestly say that it would be a good use of time creating slides and fades using pure JS when you could do it in one line with jQuery, and be sure that ti will work in every major browser.

        Lazy? Yes. Sensible? Absolutely.

    • avard says:

      I don’t get it. Why would a company be willing to waste countless hours on reinventing the wheel. Robert DeBoer, it’s time to make the freelance switch, bud!

      • Web010 says:

        I completely agree with you.
        If the company wants to stay in middle age, you don’t have too. Start freelancing.
        I am a freelancer, and the best experience was with GAF.

  2. Mystery says:

    I love you Jeff!

    Great article! :)

  3. lawrence77 says:

    wow! great article thanks!

    jeff If you publish a post means, you got 150$ or not?

  4. Jeremy says:

    I’d reverse the order of the elements of the versions array. Your code starts testing with the oldest version first, and newer versions will rarely, if ever, be used.

  5. this is awesome! thanks.

  6. R Jarrett says:

    Holy mackrel… who knew? I guess Jeff did!

  7. Just amazing! Thanks guys for sharing these premium info for free.

  8. xQlusive says:

    Thanx for this good and easy to follow tutorial!

  9. Good article, I like to see things from scratch. I wrote a guide similar to this back in December, but more in-depth (http://www.itnewb.com/archive/Beginners-Guide-to-AJAX-Asynchronous-JavaScript-and-XML).

    Keep up the good work Jeff =)

  10. Luke says:

    Nice video, very informative.

  11. Merxhan says:

    I think this is a complicated way to request a XMLHttpRequest there is a simpler raw method where you nest the if statements.

    Anyway good article

  12. Diego SA says:

    Wow, that’s cool!

  13. Ethan says:

    Very nice! I’ve always wondered how to do this…

  14. Colin McFadden says:

    You’re a workhorse, Jeff! Can’t wait to put this into practice.

  15. Yoosuf says:

    Wow jeff, its a great coz, every one is depends on Frameworks, but they don’t know what is exactly happening for response and request.

    thumbs up for u

  16. abdusfauzi says:

    this is good for basic. at least, when people are using the JS Framework, they will have this basic ideas of what is going on with the AJAX feature. nice!

  17. David Singer says:

    Iv done this once before. Now I am addicted to jQuery :)

  18. Matty says:

    Thanks for the awesome screencast, Jeff. I found it very useful and informative. :)

    Cheers,
    Matt.

  19. Jacob Gube says:

    “Raw” JavaScript – that’s a new one for me. :) Isn’t “Raw” JavaScript == just JavaScript? As opposed to using a JavaScript library that abstracts native functions and methods? Just a funny title to me is all, good Ajax script nonetheless.

    For “Raw” JavaScript, I share the following resource to beginning developers because the concept is explained really well; “Mastering Ajax, Part 2: Make asynchronous requests with JavaScript and Ajax

  20. Kanedogg says:

    Dude nice tut, always love the netutts stuff !
    nice example and easy implementation too worked right off the bat for me..

    may i ask where you learnt the method?? the only thing i did notice is the method is finely similar to that in the(pact – advanced ajax & php book) by itterating through the versions in that manner, but then again slightly different also & we all have to learn somewhere..

    Nice work i like it =o)

    • Kanedogg says:

      Oh forgot to add also this versioning can be kicked up a notch in modern browsers 7+ by incrementing the xml objects to 6 like this
      ********************************
      var versions = ["MSXML2.XmlHttp.6.0",
      "MSXML2.XmlHttp.5.0",
      "MSXML2.XmlHttp.4.0",
      "MSXML2.XmlHttp.3.0",
      "Microsoft.XmlHttp"]
      ********************************

      cheers

      • Jeffrey Way says:
        Author

        Nope. Haven’t read that book yet. Do you have a link to it? Sounds interesting.

        The code comes from a mixture of a bunch of books/sites.

    • Jeremy says:

      The technique isn’t new; I’ve used a similar function for years. Microsoft recommends checking for 6.0 and 3.0, as those two versions cover the vast majority of installations.

  21. Ibrahim says:

    About XMLHttpRequest and ActiveXObject
    this is small improvement guys work for all browsers
    function xhr(){
    return window.ActiveXObject ? new ActiveXObject(“Microsoft.XMLHTTP”) : new XMLHttpRequest();
    }

    • Jeremy says:

      That’s not an improvement at all. As far as Microsoft’s XMLHttp is concerned, you want to use the latest version available for bug fixes and better performance. The version you mention is the very first version, which is buggy and slower performing than version 6.

  22. Nick Brown says:

    Great video as always JW. As big a fan as I have become of jQuery (thanks to your screencasts) and Prototype, I originally learned Ajax in raw JavaScript and I think it’s important for others to do that as well, or at least have the option available.

  23. Phil says:

    Nicely explained, thanks.

    Are you going to return the diving into PHP series? If so, perhaps building an XML response would be uber cool!!

    thanks again!

  24. crysfel says:

    good stuff for newbies ;)

  25. Abhijit says:

    Well I kinda changed the function to accommodate a method parameter to set the method (GET or POST) and a parameter for inputting the post or get parameters. Here it is

    function load(fileName,method,params,callback)
    {
    var xhr;

    if (typeof XMLHttpRequest!==’undefined’)
    {
    xhr = new XMLHttpRequest();
    }
    else
    {
    var versions=[
    'MSXML2.XmlHttp.5.0',
    'MSXML2.XmlHttp.4.0',
    'MSXML2.XmlHttp.3.0',
    'MSXML2.XmlHttp.2.0',
    'Microsoft.XmlHttp'
    ];
    for (var i=0;i<versions.length;i++)
    {
    try
    {
    xhr = new ActiveXObject(versions[i]);
    break;
    }
    catch (e)
    {

    }
    }
    }
    xhr.onreadystatechange=function()
    {
    readyState=xhr.readyState;

    if (readyState==4)
    {
    if (xhr.status==200)
    {
    callback(xhr);
    }
    }
    }
    var queryString=”;
    if(typeof params === ‘object’)
    {
    for (var paramName in params)
    {
    queryString+=(queryString.length==0?”:’&’)+paramName+’='+encodeURIComponent(params[paramName]);
    }
    }
    var url=fileName;
    if (method.toLowerCase()==’get’)
    {
    url+=’?'+queryString;
    }
    xhr.open(method,url,true);
    if (method.toLowerCase()==’post’)
    {
    xhr.setRequestHeader(‘content-type’,'application/x-www-form-urlencoded’);
    }
    if (method.toLowerCase()==’post’)
    {
    xhr.send(queryString);
    }
    else
    {
    xhr.send(null);
    }
    }

    So, it can be called like
    load(‘get-data.php’,'POST’,{name:’abhijit’,title:’Dutta’},function(xhr)
    {
    document.getElementById(‘response’).innerHTML=xhr.responseText;
    });

    It can still be improved though and some if-else statements can be refined.

  26. Thanks for the Tutorial, man you are great. Thanks again Jeff, I like reading to your tutorials.

  27. See a ton of raw examples here – http://ajaxref.com/ch3/ The chapter before has all the non-Ajax based communications with script, iframe, image, etc. There is some library stuff later but frankly it is shown that while libraries clearly make things easy they far too often brush aside all the error cases which is simply crazy. Once you put a talkback script in you see that on the wide web your scripts fail more than you think, timeouts, retries, error handlers, etc. are required. If you don’t believe me about the issues under the hood of jquery read its source for the XMLHttpRequest wrapping…pretty light weight in terms of handling anything out of the norm.

    Keep up the good working showing the raw details it is important still at least library authors could use the data save the Dojo guys who seem to know all the nooks and cranies.

  28. Alex says:

    Great tut! While javascript libraries definitely have their place, they’re not always the best solution. One good situation to use plain javascript is when writing code that will be used by someone else, such as a WordPress plugin. Preferably a plugin should not force someone to load an extra library (it could create conflicts with a library already in use on their site).

  29. adormitu says:

    there is a minor mistake in the “XMLHttpRequest and ActiveXObject ” part of the tutorial.

    you used (in the for loop):

    # xhr = new ActiveXObject(versions[i]);
    # break;

    which will break the for loop after the first iteration, no questions asked. Instead the whole for loop should have been written like:

    # for(var i = 0, len = versions.length; i < len; i++) {
    # try {
    # xhr = new ActiveXObject(versions[i]);
    # }
    # catch (e) { continue; }
    # break;
    # }

    this way any time the object isn’t instantiated il will jump back to the try part in the for, else it will reach the break statement, meaning it succeeded in instantiating the object.

  30. juanito says:

    hello everybody.I can’t watch the video. My location:China. or can you tell me a way to download?

  31. Thank you very much for this code. It’s so clear. I saw some ajax code, but they’re not as good as this. And the explaination is excellent. Thanks again.

  32. kaam says:

    can you please tell me, how can I submit a form using ajax, where the form is in a page fetched by ajax ? Can you give a link to a full Demo??????

    Thanks.

  33. aleko says:

    it doesn’t work well in IE7

  34. flash says:

    love the way you call extra coding space “Real Estate” lol

    Great tut as usual.

  35. David Moreen says:

    I can’t believe that all of this is the equivalent of say 5 lines of jquery.

  36. Thank you! I fear more people will learn jQuery without first learning javaScript.

  37. Hassinus says:

    Greate tutorial.

    For the sceptics about knowing how to do that in RAW JS instead jQuery (and co.) :

    I had to develop a professional interface that will be used on mobile device, and it must be less than 5 kb. I just needed AJAX functions. jQuary is about 75 kb… Game over!

    Thx

Add a Comment

To add a code snippet to your comment, please wrap your code like so: <pre name="code" class="html">YOUR CODE</pre>. You can replace the class name with "js," "css," "sql," or "php." If there are any "<" or ">" within your code, please search and replace them with: &lt; and &gt; respectively.