CS 318 - Week 15 Lab - 5-8-13 a FEW words about AJAX * you should be very familiar with "basic" HTTP: * user types a URL in the browser or submits a form * web server (perhaps with the help of a Servlet engine or PHP Preprocessor) sends a response * ...a whole PAGE is the result * AJAX - short for: Asynchronous JavaScript and XML ...is a departure from this idea * something the user does in a current page prompts a request to a web server, * and there IS a response, * BUT! instead of the response being a WHOLE page that is displayed, instead the response is used by some JavaScript to make a CHANGE to the the EXISTING (currently- being displayed) page * ...do you see how there is the potential for better performance, here? tweak a bit of the page instead of reload/redraw the WHOLE page? * in a BIT more detail: * the user's web browser creates a JavaScript object called an XMLHttpRequest * The XMLHttpRequest requests some data from a web server * the data is sent back from the web server (perhaps in XML form, perhaps in JSON form, perhaps in plain text... etc.) * Once the data arrives at your browser, JavaScript "injects" that data into the web page and displays it to the user * make sure you don't fall prey to some common AJAX confusion/msconceptions: * AJAX is not a programming language * it is not a product you need to install * it's really just a catchy name for a GROUP of existing technologies and ideas already built into your web browser (if it is modern, anyway) along with some clever ways for using those technologies; * Your browser DOES need to have JavaScript enabled for AJAX to work -- BUT, for reasonably recent browsers, that's all you need to have AJAX work * let's talk about that first A, Asynchronous, a little more: * the typical paradigm isn't said to be synchronous because you load a whole page in response to a request -- the thing that makes that synchronous is that you WAIT for the new page to LOAD before you can do anything else on the page; * for asynchronous -- you allow the user to still interact with the page between the request and response -- page isn't "frozen" while you wait; * textbook definitions, Ch. 12, p. 443 * synchronous communication - "interaction that only allows ONE action at a time and forces the user to wait for that action to complete" * asynchronous communication - "interaction where MANY actions can occur at a time, in any order, without waiting for one another" * term AJAX was coined by Jess James Garrett in Feb. 2005 * building blocks of examples.... * block 1: SYNCHRONOUS JavaScript and plain Text (sjat?) var ajax = new XMLHttpRequest(); // third argument of the open method is true for // Asynchronous, false for Synchronous ajax.open("GET", "desired-url", false); ajax.send(null); // for synchronous, you don't reach this point // until the web request has completed do something with ajax.responseText * the responseText property of the XMLHttpRequest object contains the contents of the response * you can now do what you want with it! (display it, use it to determine what to do next, grab little pieces of it, etc.) * what if, then, I'd LIKE to have a Load button that, when clicked, will retrieve data from the file notes.txt and place that data inside a textarea with the id of output? window.onload = function() { var loadButton = document.getElementById("load"); loadButton.onclick = loadClick; }; function loadClick() { var ajax = new XMLHttpRequest(); ajax.open("GET", "notes.txt", false); ajax.send(null); var outputTextArea = document.getElementById("output"); outputTextArea.value = ajax.responseText; } * a working demo: see sjat-ex1.html * next step (still SJAT) -- what if the request could not be filled? then the XMLHttpRequest object's status property will contain the HTTP error code value, and its statusText property will contain any messages related to the error status * you DO get an "error" code of 200 to indicate success * SO -- you can check this status, and react differently for a non-success status value; * see sjat-ex2.html, with an example of filling a text area differently based on the value of the XMLHttpRequest's status property * NOW -- add Asynchronous! (ajat?) * so: var ajax = new XMLHttpRequest(); // 3rd argument is now true, ASYNCHRONOUS ajax.open("GET", "notes.txt", true); ajax.send(null); ..now, the next statement will be gone to, NOT waiting until the response is received; * that is: 1. you get the request STARTED, 2. send it to the server, 3. and specify a function to be called WHEN a response is received * how do we do step 3? * you attach it to an event on the XMLHttpRequest object, just like we have attached event handlers on user interface controls; * a callback - a general term for a function that is to be called later, often in response to an event * SO: attach a function as an event handler to the request's onreadystatechange event, containing the code to handle the request * we'd like to use the name of our XMLHttpRequest object -- we'll do so by setting up this handler as an anonymous function WITHIN that function that creates our XMLHttpRequest object; * the readystate CAN go through several integer values before completion -- from 0 (not initialized) to 4 (completed); we want to check for completion! var ajax = new XMLHttpRequest(); ajax.onreadystatechange = function() { if (ajax.readyState == 4) { ...then do something with ajax.responseText } }; ajax.open("GET", "desired-url", true); ajax.send(null); * see ajat-ex1.html for such an asynchronous example (but still retrieving plain text) * see course text, Ch 12, p. 450 for some more XMLHttpRequest properties and methods * AND -- adding in the X in Ajax... * another property of XMLHttpRequest object is responseXML, which is XML data that has been fetched, as a DOM Document object * represents the data as a TREE of LINKED OBJECTS * you don't to navigate this by directly walking through the child references -- instead, you call METHODS on a node to ask it for a list of its children that match a certain tag or class name * most commonly: getElementsByTagName var desired_name = ajax.responseXML.getElementsByTagName("desired_tag"); for (var i=0; i < desired_name.length; i++) { do something with the node at desired_name[i] } * see course text Chapter 12 for some "gotchas" related to the XML DOM -- for example, white space is included?! * see ajax-ex1.html for an example that grabs desired elements from XML data -- see ajax-ex2.html for an example that also grabs attribute values for certain elements;