● Asynchronous JavaScript and XML ● Combination of JavaScript, CSS, XHTML, XML, and the XMLHttpRequest object to dynamically modify a portion of a web page using data from the server ● Goal is to make web applications look and “feel” like desktop applications
Slide Set 5 1 Ajax Examples
● Google Suggest http://www.google.com/webhp?complete=1&hl=en Compare this to www.google.com where you'll see a page refresh when google returns with search results ● PHP free chat http://www.phpfreechat.net/demo.en.php ● Plastic shore chat http://www.plasticshore.com/projects/chat
Slide Set 5 2 Ajax Examples
● Online spreadsheet http://numsum.com/spreadsheet/new ● Auto completion and live search http://www.papermountain.org/demos/live ● Viewing amazon products http://lmap.co.nr/Amazon1.htm
Slide Set 5 3 A first Ajax example
● Simple example to read a text file off of the server and display the contents in a div http://www.cs.appstate.edu/~can/classes/5530/set5/ajaxgetmsg1.html
Slide Set 5 4 var XMLHttpRequestObject = false; if (window.XMLHttpRequest) //Firefox way to create object XMLHttpRequestObject = new XMLHttpRequest(); else if (window.ActiveXObject) //IE way to create object XMLHttpRequestObject = new ActiveXObject("Microsoft.XMLHTTP"); else alert("Ajax not supported"); function getData(dataSource, divID) { var obj = document.getElementById(divID); obj = obj.getElementsByTagName("p")[0]; if (XMLHttpRequestObject) { XMLHttpRequestObject.open("GET", dataSource); XMLHttpRequestObject.onreadystatechange = function() { if (XMLHttpRequestObject.readyState == 4 && XMLHttpRequestObject.status == 200) obj.innerHTML = XMLHttpRequestObject.responseText; } XMLHttpRequestObject.send(null); } else obj.innerHTML = "Ajax not supported"; } Slide Set 5 5
Fetched message will appear here.
When button is clicked, call getData passing it the name of the message file and the id of the div to hold the message
Slide Set 5 6 XMLHttpRequest object
● Allows requests for XML (and other types of data) to made and occur in the background ● Different properties and methods are available depending upon the browser
Slide Set 5 7 XMLHttpRequest properties for IE
● onreadystatechange – contains name of the event handler that should be called when the value of the readyState property changes ● readyState – contains the state of the request. read-only ● responseBody – contains a response body, which is one way HTTP responses can be returned. read-only ● responseStream – contains a response stream, a binary stream to the server. read-only ● responseText – contains the response body as a string. read-only ● responseXML – contains the response body as XML. read-only ● status – contains the HTTP status code returned by a request. read- only ● statusText – contains the HTTP response status text. read-only Slide Set 5 8 XMLHttpRequest methods for IE
● abort – aborts the HTTP request ● getAllResponseHeaders – returns all the HTTP headers ● getResponseHeader - returns the value of an HTTP header ● open – opens a request to the server ● send – sends an HTTP request to the server ● setRequestHeader – sets the name and value of an HTTP header
Slide Set 5 9 XMLHttpRequest properties for Firefox ● channel – contains the channel used to perform the request. read- only ● readyState – contains the state of the request. read-only ● responseText – contains the response body as a string. read-only ● responseXML – contains the response body as XML. read-only ● status – contains the HTTP status code returned by a request. read- only ● statusText – contains the HTTP response status text. read-only ● onreadystatechange – contains the name of the event handler that should be called when the value of the readyState property changes.
Slide Set 5 10 XMLHttpRequest methods for Firefox ● abort – aborts the HTTP request ● getAllResponseHeaders – returns all the HTTP headers ● getResponseHeader – returns the value of an HTTP header ● openRequest – native (non-script) method to open a request ● overrideMimeType – overrides the MIME type the server returns ● open – opens a request to the server ● send – sends an HTTP request to the server
Slide Set 5 11 Back to the example
● First, create the XMLHttpRequest object ● Firefox, Mozilla, Netscape (7.0+) , Safari (1.2+) method: XMLHttpRequestObject = new XMLHttpRequest(); ● IE (5.0 and above) method: XMLHttpRequestObject = new ActiveXObject("Microsoft.XMLHTTP"); ● Both of these need to be preceded by a check for whether the method is available ● Neither will work on older browsers
Slide Set 5 12 Back to the example
● Next, open a connection to a given URL using a specified method ● Syntax: open(method, url [,async, username, password]). method – GET or POST async – true (asynchronous; the default), false username/password if needed by the server ● The example: XMLHttpRequestObject.open("GET", dataSource);
Slide Set 5 13 Back to the example
● Register the event handler to be executed when the value of the readyState property changes ● The example uses a function a literal, but can be done with declarative function instead
XMLHttpRequestObject.onreadystatechange = function() { if (XMLHttpRequestObject.readyState == 4 && XMLHttpRequestObject.status == 200) obj.innerHTML = XMLHttpRequestObject.responseText; }
Slide Set 5 14 Back to the example
● Next, send the data ● If the HTTP action is a POST then the data is sent via the XMLHttpRequest send method ● Since this example is doing a GET the parameter to the send is null: XMLHttpRequestObject.send(null);
Slide Set 5 15 Back to the example
● Check the readyState property for information about the download
XMLHttpRequestObject.onreadystatechange = function() { if (XMLHttpRequestObject.readyState == 4 && XMLHttpRequestObject.status == 200) obj.innerHTML = XMLHttpRequestObject.responseText; } ● Possible property values: 0 – uninitialized, 1 – loading, 2 – loaded, 3 – interactive, 4 – complete ● During successful action, the readyState property starts at 0 and changes to 4
Slide Set 5 16 Back to the example
● Also, check the status property; same status code is retrieved by HTTP requests
XMLHttpRequestObject.onreadystatechange = function() { if (XMLHttpRequestObject.readyState == 4 && XMLHttpRequestObject.status == 200) obj.innerHTML = XMLHttpRequestObject.responseText; } ● possible property values 200 – OK, 201 – Created, 204 – No Content, 205 – Reset Content, 206- Partial Content, 400 – Bad Request, 401 – Unauthorized, 403 – Forbidden, 404 – Not Found, ... (lots more) Slide Set 5 17 Back to the example
● Finally, retrieve the data ● If the data is in XML form, retrieve from the responseXML property XMLHttpRequestObject.responseXML ● If the data is text (like in this example), retrieve from the responseText property obj.innerHTML = XMLHttpRequestObject.responseText
Slide Set 5 18 More ways to create XMLHttpRequest objects ● There are actually various versions the object available in IE – create the normal version with Microsoft.XMLHTTP ActiveX object – more recent versions available: Msxml2.XMLHTTP, Msxml2.XMLHTTP.3.0, Msxml2.XMLHTTP.4.0, Msxml2.XMLHTTP.5.0 ● A common approach to creating the object is to use nested try and catch statements
Slide Set 5 19 window.onload = getXMLHttpRequest; var XMLHttpRequestObject = false; function getXMLHttpRequest() { if (window.XMLHttpRequest) //Firefox way to create object XMLHttpRequestObject = new XMLHttpRequest(); else { try { XMLHttpRequestObject = new ActiveXObject("Msxml2.XMLHTTP"); } catch (e) { try { XMLHttpRequestObject = new ActiveXObject("Microsoft.XMLHTTP"); } catch (e) { alert("Ajax not supported"); } } } http://www.cs.appstate.edu/~can/classes/5530/set5/ajaxgetmsg2.html } Slide Set 5 20 Running server side code
● Need a server side language that can process the Ajax requests – a number of languages are available (Perl, Ruby, Java, PHP, C#, Visual Basic, ...) ● Here's a PHP program that returns text to client
Slide Set 5 21 Running server side code
● Invoking the php program
Fetched message will appear here.
http://www.cs.appstate.edu/~can/classes/5530/set5/ajaxphp1.html 22 Passing Data to PHP Script using GET ● GET uses URL encoding so data must be appended to the URL that is sent to the server ● Suppose we want to send values: a = 10 b = 32 c = “hello there” ● These would be sent like: http://www.servername.com/path/script.php?a=10&b=32&c=hello+there
Slide Set 5 23 Simple Example
● XHTML
Fetched message will appear here.
http://www.cs.appstate.edu/~can/classes/5530/set5/ajaxphp2.html
Slide Set 5 24 Simple Example
● PHP code
Slide Set 5 25 Passing data to PHP script using POST ● Using a post request, the data is encoded in the body of the message ● Modifying the simple example to use a post: – change the PHP code so that it accesses POST array instead of GET array – change the XMLHttpRequest object open to do a POST instead of a GET – call the setRequestHeader method of the XMLHttpRequest object – send the data to the server using the XMLHttpRequest object send method Slide Set 5 26 The JavaScript var XMLHttpRequestObject = false; if (window.XMLHttpRequest) //Firefox way to create object XMLHttpRequestObject = new XMLHttpRequest(); else if (window.ActiveXObject) //IE way to create object XMLHttpRequestObject = new ActiveXObject("Microsoft.XMLHTTP"); else alert("Ajax not supported"); function getData(dataSource, divID, data) { var obj = document.getElementById(divID); obj = obj.getElementsByTagName("p")[0]; if (XMLHttpRequestObject) { XMLHttpRequestObject.open("POST", dataSource); XMLHttpRequestObject.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded'); XMLHttpRequestObject.onreadystatechange = function() { if (XMLHttpRequestObject.readyState == 4 && XMLHttpRequestObject.status == 200) obj.innerHTML = XMLHttpRequestObject.responseText; } XMLHttpRequestObject.send("data=" + data); } else obj.innerHTML = "Ajax not supported"; } Slide Set 5 27 The XHTML
Fetched message will appear here.
Slide Set 5 28 The PHP script
Example at: http://www.cs.appstate.edu/~can/classes/5530/set5/ajaxphp3.html
Slide Set 5 29 Using Ajax with XML
● Need to call overrideMimeType method to force browser to treat data received from server to be XML XMLHttpRequestObject.overrideMimeType(“text/xml”); ● Callback function will access the responseXml property of the XMLHttpRequest object (instead of responseText property) xmlDocument = XMLHttpRequestObject.responseXML; ● Can use the DOM 1 implementation to access the XML
Slide Set 5 30 Ajax with XML example 1
● Example builds a drop-down list from XML obtained from the server ● GET is sent to the server to retrieve the appropriate XML file http://www.cs.appstate.edu/~can/classes/5530/set5/ajaxxml1.html
Slide Set 5 31 The XML files
northcarolina.xml maryland.xml
Slide Set 5 32 The JavaScript code, part 1
window.onload = initialize; function initialize() { getXMLHttpRequest(); //reset form to the selected item var obj = document.getElementById("myform"); obj.reset(); obj = document.getElementById("states"); obj.onchange = getSelect; } function getSelect() { var obj = document.getElementById("states"); if (obj.value == "Maryland") getData("maryland.xml"); else if (obj.value == "North Carolina") getData("northcarolina.xml");
}
Slide Set 5 33 The JavaScript code, part 2 var XMLHttpRequestObject = false; function getXMLHttpRequest() { if (window.XMLHttpRequest) //Firefox way to create object XMLHttpRequestObject = new XMLHttpRequest(); else { try { XMLHttpRequestObject = new ActiveXObject("Msxml2.XMLHTTP"); } catch (e) { try { XMLHttpRequestObject = new ActiveXObject("Microsoft.XMLHTTP"); } catch (e) { alert("Ajax not supported"); } } } }
Slide Set 5 34 The JavaScript code, part 3 function getData(dataSource) { if (XMLHttpRequestObject) { XMLHttpRequestObject.open("GET", dataSource); //need this to make Firefox treat the returned data //as xml XMLHttpRequestObject.overrideMimeType("text/xml"); XMLHttpRequestObject.onreadystatechange = function() { if (XMLHttpRequestObject.readyState == 4 && XMLHttpRequestObject.status == 200) { buildSelect(XMLHttpRequestObject.responseXML); } } XMLHttpRequestObject.send(null); } else document.getElementById("errmsg").innerHTML = "Ajax not supported"; }
Slide Set 5 35 The JavaScript code, part 4
function buildSelect(xml) { //get array of city nodes from XML var cities = xml.getElementsByTagName("city");
//get select element from HTML document var select = document.getElementById("cities");
for (var i = 0; i < cities.length; i++) { //first child of the cities node is a text node select.options[i] = new Option(cities[i].firstChild.data); } }
Slide Set 5 36 The HTML
Slide Set 5 37 Ajax with XML, example 2
● This example sends the name of the state to a PHP script on the server ● Data sent to the server via a POST ● PHP script opens a file containing state names and cities; reads through the file until the matching state name is found and dynamically builds the XML http://www.cs.appstate.edu/~can/classes/5530/set5/ajaxxml2.html
Slide Set 5 38 The states.txt file
North Carolina: Asheville Boone Charlotte Raleigh Wilmington Maryland: Annapolis Bethesda Gaithersburg Waldorf
Slide Set 5 39 The PHP code, part 1
Slide Set 5 40 The PHP code, part 2
function getData($state) { $file = fopen("states.txt", "r") or exit("Unable to open file"); $done = false; //remove backslashes (magic quotes) and quotes $state = stripslashes($state); $state = str_replace("'", "", $state); $state = str_replace('"', "", $state); $state = $state.":\n"; while ($done == false && !feof($file)) { $line = fgets($file); if (strcmp($line, $state) == 0) { $line = fgets($file); do { echo '
}
Slide Set 5 42 Some of the JavaScript, part 2 function getData(dataSource, data) { if (XMLHttpRequestObject) { XMLHttpRequestObject.open("POST", dataSource); XMLHttpRequestObject.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded'); //post header required //need this to make Firefox treat the file as an xml file XMLHttpRequestObject.overrideMimeType("text/xml"); XMLHttpRequestObject.onreadystatechange = function() { if (XMLHttpRequestObject.readyState == 4 && XMLHttpRequestObject.status == 200) { buildSelect(XMLHttpRequestObject.responseXML); } } XMLHttpRequestObject.send("data="+data); } else document.getElementById("errmsg").innerHTML = "Ajax not supported"; }
Slide Set 5 43 Handling multiple concurrent XMLHttpRequests ● What would happen if the user clicks on buttons that start up simultaneous XMLHttpRequests? – in earlier examples, only one XMLHttpRequest object is available – this one object would be modified by both requests and we wouldn't know which request is being satisfied ● Solution: – multiple XMLHttpRequest objects
Slide Set 5 44 Multiple XMLHttpRequest objects
● One solution is to store XMLHttpRequest objects in an array ● Easier and better solution is to use inner functions – every time an outer function is called, a new copy of that function (and its local variables) is created – inner functions have access to outer function local variables
Slide Set 5 45 Multiple XMLHttpRequest objects function getData(dataSource, data) { //create new XMLHttpRequest object var XMLHttpRequestObject = getXMLHttpRequest(); if (XMLHttpRequestObject) { XMLHttpRequestObject.open("POST", dataSource); XMLHttpRequestObject.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded'); //need this to make Firefox treat the file as an xml file XMLHttpRequestObject.overrideMimeType("text/xml"); XMLHttpRequestObject.onreadystatechange = function() { if (XMLHttpRequestObject.readyState == 4 && XMLHttpRequestObject.status == 200) { buildSelect(XMLHttpRequestObject.responseXML); } } XMLHttpRequestObject.send("data="+data); } else document.getElementById("errmsg").innerHTML = "Ajax not supported"; } http://www.cs.appstate.edu/~can/classes/5530/set5/ajaxxml3.html
Slide Set 5 46 Handling JavaScript sent by the server ● Don't really want the server side code to know the details of the client side code or vice-versa ● But some server-side APIs (such as Google suggest) return JavaScript ● For these, you'll have to be able to download and execute the JavaScript ● The JavaScript may be – function call – or, JavaScript object
Slide Set 5 47 window.onload = initialize; function initialize() { JavaScript sent by the //reset form to the selected item var obj = document.getElementById("mydiv"); server, Example 1 obj.onclick = getData; } function getData() { //create new XMLHttpRequest object var XMLHttpRequestObject = getXMLHttpRequest(); if (XMLHttpRequestObject) { XMLHttpRequestObject.open("GET", "ajaxjs1.php"); XMLHttpRequestObject.onreadystatechange = function() { if (XMLHttpRequestObject.readyState == 4 && XMLHttpRequestObject.status == 200) { //eval evaluates the text as JavaScript code eval(XMLHttpRequestObject.responseText); } } XMLHttpRequestObject.send(null); } else document.getElementById("errmsg").innerHTML = "Ajax not supported"; }
Slide Set 5 48 JavaScript sent by the server, Example 1
function greeting() { var obj = document.getElementById("mydiv"); obj.innerHTML = "
Hello CS 5530 Students
" }http://www.cs.appstate.edu/~can/classes/5530/set5/ajaxjs1.html
Slide Set 5 49 JavaScript sent by server, Example 2
Use PHP to create a string representing a JavaScript object
Use eval to create the JavaScript object var object; eval('object = ' + XMLHttpRequestObject.responseText);
Use eval to invoke the method specified by the object with its parameter(s)
eval(object.function + '("' + object.operand + '");'); http://www.cs.appstate.edu/~can/classes/5530/set5/ajaxjs2.html
Slide Set 5 50 Calling another domain in Ajax
● Browser will display a warning if an Ajax script tries to access a Web domain the script didn't come from ● Solution is to use a server-side script to access the domain and use Ajax to access the server- side script
Slide Set 5 51 Connecting to Google Suggest
● Can't connect to Google Suggest directly from our web page, but we can use a PHP script to connect to it ● Google Suggest returns a JavaScript function call; one of the parameters is an Array of results
Slide Set 5 52 PHP script for connecting to Google Suggest
Notice that the qu parameter for google suggest comes from my web document. URLs in PHP are opened and read from just like files.
http://www.cs.appstate.edu/~can/classes/5530/set5/google.php
Slide Set 5 53 What Google Suggest returns
● If my PHP script is invoked like this: http://www.cs.appstate.edu/~can/classes/5530/set5/google.php?qu='Mary' ● what is echoed by the script is: window.google.ac.Suggest_apply(frameElement, "\\\x27Mary\\\x27", new Array(2, "mary kay", "3,460,000 results", "mary poppins", "2,560,000 results", "mary louise parker", "2,160,000 results", "mary j blige", "2,880,000 results", "mary elizabeth winstead", "589,000 results", "mary kate olsen", "2,570,000 results", "mary kate and ashley", "3,020,000 results", "mary winkler", "1,780,000 results", "mary kay cosmetics", "1,140,000 results", "mary queen of scots", "1,470,000 results"), new Array("")); ● Notice that the third parameter contains an array of the search results
Slide Set 5 54 Eliminating Browser Caching
● Browser caching – Browser has already visited URL once and stored response from the visit (cached it) – Rather than visiting the PHP script again, browser returns result of last visit – Of course, this is bad if you are the developer and you're actively modifying the script ● Solution to this problem is to pad with the date the url so that it is unique every time
Slide Set 5 55 Eliminating Browser Caching
● Date parameter added to the URL isn't used; it is only there to cause browser to connect to server each time
XMLHttpRequestObject.open("GET", “script.php?d=' + new Date().getTime());
Slide Set 5 56 Client-side Ajax Frameworks
● Many free JavaScript code libraries are available for downloading ● Some provide support just for Ajax ● Others provide entire application solutions ● Majax (Minimalist Ajax) Framework http://sourceforge.net/projects/unips ● Sack Framework http://twilightuniverse.com/projects/sack
Slide Set 5 57 Client-side Frameworks
● XHConn Framework http://xkr.us/code/javascript/XHConn ● uniAjax Framework http://uniajax.net ● AjaxGear Framework http://www.ajaxgear.com ● AjaxRequest Framework http://www.ajaxtoolbox.com
Slide Set 5 58 Client-side Frameworks
● Http Framework (provides functionality to force or prevent caching) http://adamv.com/dev/javascript/http_request ● Interactive Website Framework (specializes in handling XML) http://sourceforge.net/projects/iwf ● Dojo http://dojotoolkit.org
Slide Set 5 59 Majax
● Small JavaScript library that provides two functions – majax_get – majax_post ● Both of these run asynchronously and plain text (no XML) is returned in the variable into the variable MAJAX_RESPONSE ● The callback function is registered using MAXCM_COMPLETE.register(callback)
Slide Set 5 60 Majax get example
Fetched message will appear here.
Fetched message will appear here.
● Open source DHTML toolkit written in JavaScript ● Three major layers – Dojo core – Dijit – widget system – DojoX – incubator area for Dojo (works in progress) ● Dojo also provides supports for Ajax
Slide Set 5 63 Dojo XHR
● Dojo XHR routines expect JSON (JavaScript Object Notation) as input ● The JSON indicates – URL – callback function – error function – what type of response to receive from server (XML, text, JavaScript, JSON) – form for posted data
Slide Set 5 64 JSON
{
url: "file.txt", handleAs: "text", timeout: 5000, load: function(response, ioArgs) { dojo.byId("cargo").innerHTML = response; return response; }, error: function(response, ioArgs) { console.error("HTTP status code: ", ioArgs.xhr.status); return response; } }
Slide Set 5 65 Dojo Example Dojo Example