Web Programming Step by Step, 2nd Edition
Lecture 23: Ajax
Reading: 12.1 - 12.2
Except where otherwise noted, the contents of this document are
Copyright 2012 Marty Stepp, Jessica Miller, and Victoria Kirst.
All rights reserved.
Any redistribution, reproduction, transmission, or storage of part
or all of the contents in any form is prohibited without the author's
expressed written permission.
Synchronous web communication
- synchronous: user must wait while new pages load
-
the typical communication pattern used in web pages (click, wait, refresh)
-
web application: a dynamic web site that mimics the feel of a desktop app
-
Ajax: Asynchronous JavaScript and XML
- not a programming language; a particular way of using JavaScript
- downloads data from a server in the background
- allows dynamically updating a page without making the user wait
- avoids the "click-wait-refresh" pattern
-
examples: UW's CSE 14x Diff Tool, Practice-It;
Google Suggest
Asynchronous web communication
- asynchronous: user can keep interacting with page while data loads
-
communication pattern made possible by Ajax
- JavaScript includes an
XMLHttpRequest
object that can fetch files from a web server
- supported in IE7+, Safari, Firefox, Opera, Chrome, etc. (all major browsers)
- IE5/6 don't have it, but we will ignore this
- (technically, MS/IE invented
XMLHttpRequest
and Ajax for use in an online version of MS Outlook (credit where it's due!)
- it can do this asynchronously (in the background, transparent to user)
- the contents of the fetched file can be put into current web page using the DOM
A typical Ajax request
- user clicks, invoking an event handler
- handler's code creates an
XMLHttpRequest
object
XMLHttpRequest
object requests page from server
- server retrieves appropriate data, sends it back
XMLHttpRequest
fires an event when data arrives
- this is often called a callback
- you can attach a handler function to this event
- your callback event handler processes the data and displays it
Levels of using XMLHttpRequest
- synchronized, text/HTML-only (SJAT?)
- asynchronous, text/HTML-only (AJAT?)
- asynchronous w/ XML data (Ajax ... seen next lecture)
the core JavaScript object that makes Ajax possible
Method |
Description |
open(method, url, async)
|
specifies the URL and HTTP request method
|
send()
send(postData)
|
sends the HTTP request to the server, with optional POST parameters
|
abort()
|
stops the request
|
getAllResponseHeaders() ,
getResponseHeader(name) ,
setRequestHeader(name, value)
|
for getting/setting raw HTTP headers
|
Property |
Description |
responseText
|
the entire text of the fetched page, as a string
|
responseXML
|
the entire contents of the fetched page, as an XML document tree (seen later)
|
status
|
the request's (200 = OK, etc.)
|
statusText
|
HTTP status code text (e.g. "Bad Request" for 400)
|
timeout
|
how many MS to wait before giving up and aborting the request (default 0 = wait forever)
|
readyState
|
request's current state (0 = not initialized, 1 = set up, 2 = sent, 3 = in progress, 4 = complete)
|
1. Synchronized requests (bad)
var ajax = new XMLHttpRequest();
ajax.open("GET", url, false);
ajax.send();
do something with ajax.responseText;
- create the request object, open a connection, send the request
- when
send
returns, the fetched text will be stored in request's responseText
property
Why synchronized requests suck
- your code waits for the request to completely finish before proceeding
- easier for you to program, but ...
- the user's entire browser LOCKS UP until the download is completed
- a terrible user experience (especially if the page is very large or slow to transfer)
- better solution: use an asynchronous request that notifies you when it is complete
- this is accomplished by learning about the event properties of
XMLHttpRequest
Event |
Description |
load
|
occurs when the request is completed
|
error
|
occurs when the request fails
|
timeout
|
occurs when the request times out
|
abort
|
occurs when the request is aborted by calling abort()
|
loadstart , loadend ,
progress , readystatechange
|
progress events to track a request in progress
|
2. Asynchronous requests, basic idea
var ajax = new XMLHttpRequest();
ajax.onload = functionName;
ajax.open("GET", url, true);
ajax.send();
...
function functionName() {
do something with this.responseText
;
}
- attach an event handler to the
load
event
- handler will be called when request state changes, e.g. finishes
- function contains code to run when request is complete
- inside your handler function,
this
will refer to the ajax
object
- you can access its
responseText
and other properties
What if the request fails?
var ajax = new XMLHttpRequest();
ajax.onload = functionName;
ajax.open("GET", "url", true);
ajax.send();
...
function functionName() {
if (this.status == 200) {
do something with this.responseText
;
} else {
code to handle the error;
}
}
- web servers return status codes for requests (200 means Success)
- you may wish to display a message or take action on a failed request
Handling the error event
var ajax = new XMLHttpRequest();
ajax.onload = functionName;
ajax.onerror = errorFunctionName;
ajax.open("GET", "url", true);
ajax.send();
...
function functionName(e) {
do something with e
, this.status
, this.statusText
, ...
}
- the graceful way to handle errors is to listen for the
error
event
- the handler is passed the error/exception as a parameter
- you can examine the error, as well as the request status, to determine what went wrong
Example Ajax error handler
var ajax = new XMLHttpRequest();
...
ajax.onerror = ajaxFailure;
...
function ajaxFailure(exception) {
alert("Error making Ajax request:" +
"\n\nServer status:\n" + this.status + " " + this.statusText +
"\n\nServer response text:\n" + this.responseText);
if (exception) {
throw exception;
}
}
- for user's (and developer's) benefit, show an error message if a request fails
Debugging Ajax code
- Firebug Net tab (or Chrome's Network tab) shows each request, parameters, response, errors
- expand a request with + and look at Response tab to see Ajax result
- check Console tab for any errors that are thrown by requests
Passing query parameters to a request
var ajax = new XMLHttpRequest();
ajax.onload = functionName;
ajax.open("GET", "url?name1=value1&name2=value2&...", true);
ajax.send();
- to pass parameters, concatenate them to the URL yourself
- you may need to URL-encode the parameters by calling the JS
escape(string)
function on them
- won't work for POST requests (see next slide)
Creating a POST
request
var params = new FormData();
params.append("name", value);
params.append("name", value);
var ajax = new XMLHttpRequest();
ajax.onload = functionName;
ajax.open("POST", "url", true);
ajax.send(params);
- use a object to gather your POST query parameters
- pass the
FormData
to the request's send
method
method
passed to open
should be changed to "POST"
XMLHttpRequest
security restrictions
- Ajax must be run on a web page stored on a web server
- (cannot be run from a web page stored on your hard drive)
- Ajax can only fetch files from the same server that the page is on
http://www.foo.com/a/b/c.html
can only fetch from http://www.foo.com