Ajax Asynchronous JavaScript and XML Combination of JavaScript, - - PowerPoint PPT Presentation

ajax
SMART_READER_LITE
LIVE PREVIEW

Ajax Asynchronous JavaScript and XML Combination of JavaScript, - - PowerPoint PPT Presentation

Ajax 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


slide-1
SLIDE 1

Slide Set 5 1

Ajax

  • 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-2
SLIDE 2

Slide Set 5 2

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-3
SLIDE 3

Slide Set 5 3

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-4
SLIDE 4

Slide Set 5 4

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-5
SLIDE 5

Slide Set 5 5

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);

  • bj = obj.getElementsByTagName("p")[0];

if (XMLHttpRequestObject) { XMLHttpRequestObject.open("GET", dataSource); XMLHttpRequestObject.onreadystatechange = function() { if (XMLHttpRequestObject.readyState == 4 && XMLHttpRequestObject.status == 200)

  • bj.innerHTML = XMLHttpRequestObject.responseText;

} XMLHttpRequestObject.send(null); } else

  • bj.innerHTML = "Ajax not supported";

}

slide-6
SLIDE 6

Slide Set 5 6

<body> <form action=""> <p> <input type="button" value="Fetch the message"

  • nclick = "getData('msg.txt', 'targetDiv')" />

</p> </form> <div id="targetDiv"> <p>Fetched message will appear here.</p> </div> </body>

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-7
SLIDE 7

Slide Set 5 7

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-8
SLIDE 8

Slide Set 5 8

XMLHttpRequest properties for IE

  • nreadystatechange – 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-
  • nly
  • statusText – contains the HTTP response status text. read-only
slide-9
SLIDE 9

Slide Set 5 9

XMLHttpRequest methods for IE

  • abort – aborts the HTTP request
  • getAllResponseHeaders – returns all the HTTP headers
  • getResponseHeader - returns the value of an HTTP header
  • pen – 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-10
SLIDE 10

Slide Set 5 10

XMLHttpRequest properties for Firefox

  • channel – contains the channel used to perform the request. read-
  • nly
  • 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-
  • nly
  • statusText – contains the HTTP response status text. read-only
  • nreadystatechange – contains the name of the event handler that

should be called when the value of the readyState property changes.

slide-11
SLIDE 11

Slide Set 5 11

XMLHttpRequest methods for Firefox

  • abort – aborts the HTTP request
  • getAllResponseHeaders – returns all the HTTP headers
  • getResponseHeader – returns the value of an HTTP header
  • penRequest – native (non-script) method to open a request
  • verrideMimeType – overrides the MIME type the server returns
  • pen – opens a request to the server
  • send – sends an HTTP request to the server
slide-12
SLIDE 12

Slide Set 5 12

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-13
SLIDE 13

Slide Set 5 13

Back to the example

  • Next, open a connection to a given URL using a

specified method

  • Syntax:
  • pen(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-14
SLIDE 14

Slide Set 5 14

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)

  • bj.innerHTML = XMLHttpRequestObject.responseText;

}

slide-15
SLIDE 15

Slide Set 5 15

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-16
SLIDE 16

Slide Set 5 16

Back to the example

  • Check the readyState property for information

about the download XMLHttpRequestObject.onreadystatechange = function()

{ if (XMLHttpRequestObject.readyState == 4 && XMLHttpRequestObject.status == 200)

  • bj.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-17
SLIDE 17

Slide Set 5 17

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)

  • bj.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-18
SLIDE 18

Slide Set 5 18

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

  • bj.innerHTML = XMLHttpRequestObject.responseText
slide-19
SLIDE 19

Slide Set 5 19

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-20
SLIDE 20

Slide Set 5 20

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-21
SLIDE 21

Slide Set 5 21

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

<?php echo 'Welcome to Ajax!' ?>

slide-22
SLIDE 22

22

Running server side code

  • Invoking the php program

<body> <form action=""> <p> <input type="button" value="Fetch the message"

  • nclick = "getData('ajaxphp1.php', 'targetDiv')" />

</p> </form> <div id="targetDiv"> <p>Fetched message will appear here.</p> </div> </body>

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

slide-23
SLIDE 23

Slide Set 5 23

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-24
SLIDE 24

Slide Set 5 24

Simple Example

  • XHTML

<form action=""> <p> <input type="button" value="Fetch message 1"

  • nclick = "getData('ajaxphp2.php?data=1', 'targetDiv')" />

<input type="button" value="Fetch message 2"

  • nclick = "getData('ajaxphp2.php?data=2', 'targetDiv')" />

</p> </form> <div id="targetDiv"> <p>Fetched message will appear here.</p> </div>

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

slide-25
SLIDE 25

Slide Set 5 25

Simple Example

  • PHP code

<?php extract($_GET); if ($data == "1") echo 'Welcome to Ajax!'; if ($data == "2") echo 'Ajax is fun!'; ?>

slide-26
SLIDE 26

Slide Set 5 26

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

  • bject send method
slide-27
SLIDE 27

Slide Set 5 27

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);

  • bj = 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)

  • bj.innerHTML = XMLHttpRequestObject.responseText;

} XMLHttpRequestObject.send("data=" + data); } else

  • bj.innerHTML = "Ajax not supported";

}

The JavaScript

slide-28
SLIDE 28

Slide Set 5 28

<body> <form action=""> <p> <input type="button" value="Fetch message 1"

  • nclick = "getData('ajaxphp3.php', 'targetDiv', 1)" />

<input type="button" value="Fetch message 2"

  • nclick = "getData('ajaxphp3.php', 'targetDiv', 2)" />

</p> </form> <div id="targetDiv"> <p>Fetched message will appear here.</p> </div> </body>

The XHTML

slide-29
SLIDE 29

Slide Set 5 29

<?php extract($_POST); if ($data == "1") echo 'Welcome to Ajax!'; if ($data == "2") echo 'Ajax is fun!'; ?>

The PHP script

Example at: http://www.cs.appstate.edu/~can/classes/5530/set5/ajaxphp3.html

slide-30
SLIDE 30

Slide Set 5 30

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

  • f responseText property)

xmlDocument = XMLHttpRequestObject.responseXML;

  • Can use the DOM 1 implementation to access

the XML

slide-31
SLIDE 31

Slide Set 5 31

Ajax with XML example 1

  • Example builds a drop-down list from XML
  • btained 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-32
SLIDE 32

Slide Set 5 32

The XML files

<?xml version = "1.0" ?> <cities> <city>Asheville</city> <city>Boone</city> <city>Charlotte</city> <city>Raleigh</city> <city>Wilmington</city> </cities> <?xml version = "1.0" ?> <cities> <city>Annapolis</city> <city>Bethesda</city> <city>Gaithersburg</city> <city>Waldorf</city> </cities> northcarolina.xml maryland.xml

slide-33
SLIDE 33

Slide Set 5 33

window.onload = initialize; function initialize() { getXMLHttpRequest(); //reset form to the selected item var obj = document.getElementById("myform");

  • bj.reset();
  • bj = document.getElementById("states");
  • bj.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"); }

The JavaScript code, part 1

slide-34
SLIDE 34

Slide Set 5 34

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-35
SLIDE 35

Slide Set 5 35

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-36
SLIDE 36

Slide Set 5 36

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-37
SLIDE 37

Slide Set 5 37

The HTML

<body> <form id="myform" action=""> <p> <select size="1" id="states"> <option value="">Select a State</option> <option value="Maryland">Maryland</option> <option value="North Carolina">North Carolina</option> </select> </p> <p> <select size="1" id="cities"> </select> </p> </form> <div id ="errmsg"> </div> </body>

slide-38
SLIDE 38

Slide Set 5 38

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-39
SLIDE 39

Slide Set 5 39

The states.txt file

North Carolina: Asheville Boone Charlotte Raleigh Wilmington Maryland: Annapolis Bethesda Gaithersburg Waldorf

slide-40
SLIDE 40

Slide Set 5 40

The PHP code, part 1

<?php extract($_POST); echo '<?xml version="1.0" ?><cities>'; getData($data); echo '</cities>';

slide-41
SLIDE 41

Slide Set 5 41

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 '<city>'.$line.'</city>'; $line = fgets($file); } while (!feof($file) && strpos($line, ':') === false); $done = true; } } } ?>

slide-42
SLIDE 42

Slide Set 5 42

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-43
SLIDE 43

Slide Set 5 43

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-44
SLIDE 44

Slide Set 5 44

Handling multiple concurrent XMLHttpRequests

  • What would happen if the user clicks on buttons

that start up simultaneous XMLHttpRequests?

– in earlier examples, only one XMLHttpRequest

  • bject 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-45
SLIDE 45

Slide Set 5 45

Multiple XMLHttpRequest objects

  • One solution is to store XMLHttpRequest
  • bjects 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-46
SLIDE 46

Slide Set 5 46

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-47
SLIDE 47

Slide Set 5 47

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-48
SLIDE 48

Slide Set 5 48

window.onload = initialize; function initialize() { //reset form to the selected item var obj = document.getElementById("mydiv");

  • bj.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"; }

JavaScript sent by the server, Example 1

slide-49
SLIDE 49

Slide Set 5 49

JavaScript sent by the server, Example 1

function greeting() { var obj = document.getElementById("mydiv");

  • bj.innerHTML = "<h2>Hello CS 5530 Students</h2>"

} <?php echo "greeting();" ?> http://www.cs.appstate.edu/~can/classes/5530/set5/ajaxjs1.html

slide-50
SLIDE 50

Slide Set 5 50

JavaScript sent by server, Example 2

Use PHP to create a string representing a JavaScript object <?php $text = "{function: 'greeting', operand: 'CS 5530'};"; echo $text; ?> 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-51
SLIDE 51

Slide Set 5 51

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-52
SLIDE 52

Slide Set 5 52

Connecting to Google Suggest

  • Can't connect to Google Suggest directly from
  • ur 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-53
SLIDE 53

Slide Set 5 53

PHP script for connecting to Google Suggest

<?php $data = urlencode($_GET["qu"]); $file = fopen("http://www.google.com/complete/search?h1=en&js=true&qu=". $data, "r"); while (!feof($file)) { $line = fgets($file); echo $line; } ?> 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-54
SLIDE 54

Slide Set 5 54

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-55
SLIDE 55

Slide Set 5 55

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-56
SLIDE 56

Slide Set 5 56

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-57
SLIDE 57

Slide Set 5 57

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-58
SLIDE 58

Slide Set 5 58

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-59
SLIDE 59

Slide Set 5 59

Client-side Frameworks

  • Http Framework (provides functionality to force
  • r 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-60
SLIDE 60

Slide Set 5 60

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-61
SLIDE 61

61

Majax get example

<script type="text/javascript" src="majax-0.1.1/majax.js"></script> <script type="text/javascript" > //<![CDATA[ function getData(dataSource) { //pass the url to majax get majax_get(dataSource, null); } function handler() { var div=document.getElementById("targetDiv"); div.innerHTML = MAJAX_RESPONSE; } //register the XMLHttpRequest done handler MAJAXCM_COMPLETE.register(handler); //]]> </script> </head> <body> <form action=""> <p><input type="button" value="Fetch the message" onclick = "getData('msg.txt')" /></p> </form> <div id="targetDiv"> <p>Fetched message will appear here.</p> </div>

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

slide-62
SLIDE 62

62

Majax post example

<script type="text/javascript" src="majax-0.1.1/majax.js"></script> <script type="text/javascript" > //<![CDATA[ function getData(dataSource, data) { //pass the url to majax get majax_post(dataSource, "str="+data); } function handler() { var div=document.getElementById("targetDiv"); div.innerHTML = MAJAX_RESPONSE; } //register the XMLHttpRequest done handler MAJAXCM_COMPLETE.register(handler); //]]> </script> </head> <body> <form action=""> <p> <input type="button" value="Fetch the message" onclick = "getData('majaxgetmsg2.php', 'CS 5530')" /></p> </form> <div id="targetDiv"><p>Fetched message will appear here.</p></div>

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

slide-63
SLIDE 63

Slide Set 5 63

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-64
SLIDE 64

Slide Set 5 64

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-65
SLIDE 65

Slide Set 5 65

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-66
SLIDE 66

Slide Set 5 66

Dojo Example

<script type="text/javascript" src="http://o.aolcdn.com/dojo/0.9.0/dojo/dojo.xd.js"></script> <script type="text/javascript"> //<![CDATA[ function hello() { dojo.xhrGet( { //The following URL must match that used to test the server. url: "http://www.cs.appstate.edu/~can/classes/5530/set5/msg.txt", handleAs: "text", timeout: 5000, // Time in milliseconds // The LOAD function will be called on a successful response. 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; } }); } //]]> </script>

slide-67
SLIDE 67

Slide Set 5 67

Dojo Example

<script type="text/javascript"> //<![CDATA[ dojo.addOnLoad(hello); //]]> </script> </head> <body> <div id="cargo" style="font-size: big"></div> <!--.--> </body> </html> 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-68
SLIDE 68

Slide Set 5 68

Sending data to server

  • When using xhrGet, you can append data to the

URL:

  • However, this only supports static data;

dynamic data must be sent using xhrPost by specifying the id of the form holding the data

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

slide-69
SLIDE 69

Slide Set 5 69

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-70
SLIDE 70

Slide Set 5 70

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-71
SLIDE 71

Slide Set 5 71

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-72
SLIDE 72

Slide Set 5 72

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-73
SLIDE 73

Slide Set 5 73

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-74
SLIDE 74

Slide Set 5 74

Sajax Example

<? require("sajax-0.12/php/Sajax.php"); // The server code that does the work. function adder($operand1, $operand2) { return $operand1 + $operand2; } sajax_init(); sajax_export("adder"); sajax_handle_client_request(); ?>

PHP code at top of file

slide-75
SLIDE 75

Slide Set 5 75

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" /> <title>Sajax Example</title> <script type="text/javascript"> //<![CDATA[ <? sajax_show_javascript(); ?> function do_adder() { var operand1, operand2;

  • perand1 = document.getElementById("operand1").value;
  • perand2 = document.getElementById("operand2").value;

x_adder(operand1, operand2, show_results); } function show_results(result) { document.getElementById("result").value = result; } //]]> </script> </head>

PHP code followed by web document sent to client

slide-76
SLIDE 76

Slide Set 5 76

<body> <h1>Sajax Example</h1> <p> <input type="text" name="operand1" id="operand1" value="4" size="3" /> + <input type="text" name="operand2" id="operand2" value="5" size="3" /> = <input type="text" name="result" id="result" value="" size="3" /> <input type="button" name="check" value="Add" onclick="do_adder(); return false; /> </p> </body> </html> http://www.cs.appstate.edu/~can/classes/5530/set5/sajax1.php

Here's the rest of the document

slide-77
SLIDE 77

Slide Set 5 77

Sajax Example

  • The call to x_adder causes a call to be made to

adder in the PHP script

  • Body of x_adder

function x_adder() { sajax_do_call("adder", x_adder.arguments); }

  • x_adder.arguments is the array of arguments

passed to x_adder; last argument is the name

  • f the JavaScript function to be executed when

server responds

  • sajax_do_call does the Ajax work
slide-78
SLIDE 78

Slide Set 5 78

Ajax Example

  • Downloading an image from the server
  • Image name is retrieved from the server using

Ajax and then an <img> 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-79
SLIDE 79

Slide Set 5 79

window.onload = initialize; function initialize() { var obj = document.getElementById("Dog");

  • bj.onclick = getImage;

var obj = document.getElementById("Cat");

  • bj.onclick = getImage;

}

The JavaScript

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-80
SLIDE 80

Slide Set 5 80

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-81
SLIDE 81

Slide Set 5 81

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) {

  • bj = document.getElementById("imageLoc");
  • bj.innerHTML = '<img src="' + imageName + '" alt="A Pic" />';

}

slide-82
SLIDE 82

Slide Set 5 82

The HTML

<body> <form id="myform" action=""> <p> <input type="button" id="Dog" value="Show Dog Image" /> <input type="button" id="Cat" value="Show Cat Image" /> </p> </form> <div id ="imageLoc"> </div> </body> http://www.cs.appstate.edu/~can/classes/5530/set5/downloadimage.html

slide-83
SLIDE 83

Slide Set 5 83

<?php extract($_POST); getData($data); 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"; } ?>

The PHP

slide-84
SLIDE 84

Slide Set 5 84

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-85
SLIDE 85

Slide Set 5 85

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-86
SLIDE 86

Slide Set 5 86

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-87
SLIDE 87

87

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"; }

slide-88
SLIDE 88

Slide Set 5 88

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-89
SLIDE 89

Slide Set 5 89

JavaScript built-in properties (review)

  • attributes
  • childNodes
  • documentElement

(root element)

  • firstChild
  • lastChild
  • localName (without

namespace)

  • nextSibling
  • nodeName
  • nodeType
  • nodeValue
  • previousSibling
slide-90
SLIDE 90

Slide Set 5 90

nodeType property values

  • 1 – Element
  • 2 – Attribute
  • 3 – Text node
  • 4 – CDATA
  • 5 – XML entity

reference

  • 6 – XML entity node
  • 7 – XML processing

instruction

  • 8 – XML comment
  • 9 – XML document

node

  • 10 – XML DTD
  • 11 – XML document

fragment

  • 12 – XML Notation
slide-91
SLIDE 91

Slide Set 5 91

XML Example

<?xml version="1.0"?> <!DOCTYPE name [ <!ELEMENT name (first, last) > <!ELEMENT first (#PCDATA) > <!ELEMENT last (#PCDATA) > <!ENTITY mr "Mister"> ]> <name> <first>&mr; Jack</first> <last>Sprat</last> </name> http://www.cs.appstate.edu/~can/classes/5530/set5/name.xml

slide-92
SLIDE 92

Slide Set 5 92

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, "<h2>XML document</h2>" + XMLstr.str); }

slide-93
SLIDE 93

93

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; for (var i = 0; i < children.length; i++) this.str = this.str + children[i].nodeName + " "; this.str = this.str + " }\n"; //visit the next level for (var i = 0; i < children.length; i++) this.traverse(level + 1, children[i]) } else this.str = this.str + "\n"; } } Of course, this is just like our JavaScript to traverse an XHTML document. http://www.cs.appstate.edu/~can/classes/5530/set5/name.html

slide-94
SLIDE 94

94

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

slide-95
SLIDE 95

Slide Set 5 95

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-96
SLIDE 96

Slide Set 5 96

Retrieving attributes

  • XML

<member role=”chair”>Sally Worker</member>

  • 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-97
SLIDE 97

Slide Set 5 97

<?xml version="1.0"?> <events> <event type="Food"> <event_title>Cookie Dough Fundraiser</event_title> <committee> <member role="chair">Jane Doe</member> <member role="secretary">Jack Sprat</member> <member role="at large">Carol Smith</member> </committee> </event> <event type="Fair"> <event_title>Fall Festival Fundraiser</event_title> <committee> <member role="chair">Sally Chair</member> <member role="secretary">John Helper</member> <member role="at large">Carol Smith</member> </committee> </event> <event type="Food"> <event_title>Donut Sale</event_title> <committee> <member role="chair">Ruth Member</member> <member role="secretary">Eric Serve</member> <member role="at large">Connie Adams</member> <member role="at large">Henry Assistant</member> </committee> </event> </events>

fundraising.xml

slide-98
SLIDE 98

98

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"); table.border = "5px"; var row = table.insertRow(-1); var cell1 = row.insertCell(0); var cell2 = row.insertCell(1); cell1.innerHTML = "<b>Event</b>"; cell2.innerHTML = "<b>Chair</b>"; 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); } Builds table of fundraising events and the chairs http://www.cs.appstate.edu/~can/classes/5530/set5/fundraising.html

slide-99
SLIDE 99

Slide Set 5 99

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-100
SLIDE 100

Slide Set 5 100

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.

<script type=”text/javascript”>window.location=www.malicious.com</script>

– one solution to this problem is to convert sensitive

html characters < and > to equivalents &lt; and &gt;

slide-101
SLIDE 101

Slide Set 5 101

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)