● 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+) , (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 (, 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

Asheville Annapolis Boone Bethesda Charlotte Gaithersburg Raleigh Waldorf Wilmington

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

'; getData($data); echo '';

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 ''.$line.''; $line = fgets($file); } while (!feof($file) && strpos($line, ':') === false); $done = true; } } } ?> Slide Set 5 41 Some of the JavaScript, part 1 function getSelect() { var obj = document.getElementById("states"); if (obj.value == "Maryland") getData("ajaxxml2.php", "Maryland"); else if (obj.value == "North Carolina") getData("ajaxxml2.php", "North Carolina");

}

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 ● 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 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.

ht tp://www.cs.appstate.edu/~can/classes/5530/set5/majaxgetmsg1.html 61 Majax post example

Fetched message will appear here.

http://www.cs.appstate.edu/~can/classes/5530/set5/majaxgetmsg2.html 62 Dojo

● 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

http://www.cs.appstate.edu/~can/classes/5530/set5/dojohello1.html

Welcome to Ajax!

http://www.cs.appstate.edu/~can/classes/5530/set5/msg.txt

Slide Set 5 67 Sending data to server

● When using xhrGet, you can append data to the URL:

url: "http://www.cs.appstate.edu/~can/classes/5530/set5/dojohello2.php?str='CS 5530'",

● However, this only supports static data; dynamic data must be sent using xhrPost by specifying the id of the form holding the data

Slide Set 5 68 Server-Side Ajax Frameworks

● These help with both server-side programming and client-side programming ● Framework can generate the JavaScript needed by the browser ● Frameworks are available in many different languages including PHP, Java, Ruby, Python, Perl and more

Slide Set 5 69 Server-Side Ajax Frameworks

● Sajax http://www.modernmethod.com/sajax ● Xajax http://xajax.sf.net ● LibAjax http://sourceforge.net/projects/libajax ● Direct Web Remoting and Java http://getahead.ltd.uk/dwr

Slide Set 5 70 Server-Side Ajax Frameworks

● Ajax Tag Library and Java (relies on JSP custom tags) http://ajaxtags.sourceforge.net ● Swato and Java https://swato.dev.java.net/ ● Ruby on Rails http://rubyonrails.com/down

Slide Set 5 71 Sajax

● Creates JavaScript on the server that is needed by the browser so all you need is server-side code ● Can be written in many different languages including ASP, ColdFusion, Lua, Perl, Python, Ruby, Io ● When the browser requests a PHP (or other) script stored on the server, the script is executed and the JavaScript generated is sent to the browser

Slide Set 5 72 Sajax

● Sajax provides functionality to connect the server-side code to the JavaScript coded ● Important Sajax functions – sajax_init(); //sets up Sajax – sajax_export(“function”); //makes a server-side function available to JavaScript function – sajax_handle_client_request(); //connects server- side and client-side code – sajax_show_javascript(); //generates the JavaScript

Slide Set 5 73 Sajax Example

PHP code at top of file

Slide Set 5 74 PHP code followed by web document sent to client

Sajax Example Slide Set 5 75 Here's the rest of the document

Sajax Example

+ =

● Downloading an image from the server ● Image name is retrieved from the server using Ajax and then an element is built using the image name ● This is useful when the application developer doesn't know the name of the images on the server; for example, if the images initially come from the client

Slide Set 5 78 The JavaScript window.onload = initialize; function initialize() { var obj = document.getElementById("Dog"); obj.onclick = getImage; var obj = document.getElementById("Cat"); obj.onclick = getImage; } function getImage() { var obj = document.getElementById("Dog"); if (obj == this) getData("downloadimage.php", "Dog"); var obj = document.getElementById("Cat"); if (obj == this) getData("downloadimage.php", "Cat"); }

Slide Set 5 79 The JavaScript function getXMLHttpRequest() { if (window.XMLHttpRequest) //Firefox way to create object return new XMLHttpRequest(); else { try { return new ActiveXObject("Msxml2.XMLHTTP"); } catch (e) { try { return new ActiveXObject("Microsoft.XMLHTTP"); } catch (e) { alert("Ajax not supported"); return null; } } } }

Slide Set 5 80 The JavaScript 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'); XMLHttpRequestObject.onreadystatechange = function() { if (XMLHttpRequestObject.readyState == 4 && XMLHttpRequestObject.status == 200) { displayImage(XMLHttpRequestObject.responseText); } } XMLHttpRequestObject.send("data="+data); } else document.getElementById("errmsg").innerHTML = "Ajax not supported"; } function displayImage(imageName) { obj = document.getElementById("imageLoc"); obj.innerHTML = ''; } Slide Set 5 81 The HTML

http://www.cs.appstate.edu/~can/classes/5530/set5/downloadimage.html

Slide Set 5 82 The PHP

function getData($image) { //remove backslashes (magic quotes) and quotes $image = stripslashes($image); $image = str_replace("'", "", $image); $image = str_replace('"', "", $image); if (strcmp($image, "Dog") == 0) echo "dog.jpg"; else if (strcmp($image, "Cat") == 0) echo "cat.jpg"; else echo $image." not found"; } ?>

Slide Set 5 83 Ajax Timeout

● What should you do if the server doesn't respond? ● Display an alert or error message so that the user can retry or give up ● Don't want user to be left in the dark, wondering what is happening

Slide Set 5 84 Ajax Timeout

● Timeout function – create one that will be executed after some period of time executes; will display an alert message if server hasn't responded ● Two variables – timeoutSet – initially false; set to true if a timeout function has been set (keeps timeout being set again) – downloadOK – initially false; set to true if successful download occurs (prevents timeout function from displaying alert message) Slide Set 5 85 Ajax Timeout

function getImage() { var obj = document.getElementById("Dog"); //deliberately mis-name php script to see my timeout alert if (obj == this) getData("downloadimag.php", "Dog"); var obj = document.getElementById("Cat"); if (obj == this) getData("downloadimage.php", "Cat"); }

http://www.cs.appstate.edu/~can/classes/5530/set5/timeout.html

Slide Set 5 86 function getData(dataSource, data) { var XMLHttpRequestObject = getXMLHttpRequest(); if (XMLHttpRequestObject) { XMLHttpRequestObject.open("POST", dataSource); XMLHttpRequestObject.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded'); var timeoutSet = false; var downloadOK = false; XMLHttpRequestObject.onreadystatechange = function() { if (XMLHttpRequestObject.readyState == 1 && timeoutSet == false) { window.setTimeout( function() { if (!downloadOK) { alert("Sorry, time out."); XMLHttpRequestObject.abort(); } }, 1000); //call function literal in 1000 milliseconds timeoutSet = true; }

if (XMLHttpRequestObject.readyState == 4 && XMLHttpRequestObject.status == 200) { downloadOK = true; displayImage(XMLHttpRequestObject.responseText); } } XMLHttpRequestObject.send("data="+data); } else document.getElementById("errmsg").innerHTML = "Ajax not supported"; } 87 XML and Ajax

● XML is a text based way of storing data which is why it is so popular for the internet ● Two versions available, 1.0 and 1.1 (1.1 supports a larger character set) ● Two primary correctness criteria – well-formedness – legal tags and nesting – validity – ● what the tags are; which tags must be nested within other tags ● specified by a DTD or an XML schema Slide Set 5 88 JavaScript built-in properties (review) ● attributes ● nextSibling ● childNodes ● nodeName ● documentElement ● nodeType (root element) ● nodeValue ● firstChild ● previousSibling ● lastChild ● localName (without namespace)

Slide Set 5 89 nodeType property values

● 1 – Element ● 8 – XML comment ● 2 – Attribute ● 9 – XML document ● 3 – Text node node ● ● 4 – CDATA 10 – XML DTD ● ● 5 – XML entity 11 – XML document reference fragment ● ● 6 – XML entity node 12 – XML Notation ● 7 – XML processing instruction Slide Set 5 90 XML Example

]> &mr; Jack Sprat

http://www.cs.appstate.edu/~can/classes/5530/set5/name.xml

Slide Set 5 91 JavaScript to traverse the XML

handleXML(XMLHttpRequestObject.responseXML);

function handleXML(xml) { var XMLstr = new stringTree(); XMLstr.traverse(0, xml); var obj = document.getElementById("mydiv1"); displayData(obj, "

XML document

" + XMLstr.str); }

Slide Set 5 92 JavaScript to traverse XML function stringTree() { this.str = ""; this.traverse = function traverse(level, node) { this.str = this.str + "Level: " + level + ", Node Name: " + node.nodeName + ", Node Type: " + node.nodeType + ", Node Value: " + node.nodeValue; if (node.hasChildNodes()) { this.str = this.str + " { "; var children = node.childNodes; Of course, this is for (var i = 0; i < children.length; i++) just like our JavaScript this.str = this.str + children[i].nodeName + " "; to traverse an XHTML this.str = this.str + " }\n"; document. //visit the next level for (var i = 0; i < children.length; i++) this.traverse(level + 1, children[i]) } else this.str = this.str + "\n"; } }

93 http://www.cs.appstate.edu/~can/classes/5530/set5/name.html Differences in Document Tree

● If you view the URL indicated on the previous slide in IE and Firefox, you'll notice they generate very different document trees ● Major difference is due to whitespace outside of the elements – Firefox creates nodes for this whitespace; IE does not

94 JavaScript to remove whitespace

function removeWhiteSpace(xml) { var i; for (i = 0; i < xml.childNodes.length; i++) { var currentNode = xml.childNodes[i]; if (currentNode.nodeType == 1) { //element node removeWhiteSpace(currentNode); } if (((/^\s+$/.test(currentNode.nodeValue))) && (currentNode.nodeType == 3)) { //empty text node xml.removeChild(xml.childNodes[i--]); } } }

http://www.cs.appstate.edu/~can/classes/5530/set5/name2.html

Slide Set 5 95 Retrieving attributes

● XML Sally Worker ● Would like to retrieve the value of the role attribute ● Assuming obj points to the member node: attributes = obj.attributes; // attributes of this member node value = attributes.getNamedItem(“role”); // role attribute value

Slide Set 5 96 Cookie Dough Fundraiser Jane Doe Jack Sprat Carol Smith Fall Festival Fundraiser Sally Chair fundraising.xml John Helper Carol Smith Donut Sale Ruth Member Eric Serve Connie Adams Henry Assistant

Slide Set 5 97 function handleXML(xml) { var titles = xml.getElementsByTagName("event_title"); var committees = xml.getElementsByTagName("committee"); var i = 0; var j = 0; var table = document.createElement("table"); Builds table of table.border = "5px"; fundraising events and the var row = table.insertRow(-1); chairs var cell1 = row.insertCell(0); var cell2 = row.insertCell(1); cell1.innerHTML = "Event"; cell2.innerHTML = "Chair"; for (i = 0; i < titles.length; i++) { var members = committees[i].getElementsByTagName("member"); for (j = 0; j < members.length; j++) { var attributes = members[j].attributes; if (attributes.getNamedItem("role").nodeValue == "chair") var chair = members[j].firstChild.nodeValue; } row = table.insertRow(-1); cell1 = row.insertCell(0); cell2 = row.insertCell(1); cell1.innerHTML = titles[i].firstChild.nodeValue; cell2.innerHTML = chair; } document.getElementById("mydiv").appendChild(table); } 98 http://www.cs.appstate.edu/~can/classes/5530/set5/fundraising.html Ajax and Security

● JavaScript is visible no matter its location (embedded, in a separate .js file, or generated by a script on the server) ● Users can look at your JavaScript, figure out how to call a script on the server, and pass the script fictitious data scorekeeper.php?score=2221 ● You can try to make your JavaScript less readable http://www.semdesigns.com/Products/Obfuscators/ Slide Set 5 99 Ajax and Security

● Keep proprietary code on the server; never expose more code than is necessary ● Be aware that users can enter JavaScript code as a response and when that JavaScript is displayed on a browser, it is executed. – one solution to this problem is to convert sensitive html characters < and > to equivalents < and >

Slide Set 5 100 Ajax and Security

● Accesses outside of bounds of an array – illegal array indices can be accessed to overwrite legitimate code – solution is to simply do bounds checking ● Password protection – do it yourself (ask user for a password) – server-side authentication – users automatically asked for a username/password when site is accessed ● HTTPS (secure protocol) Slide Set 5 101