You are on page 1of 6

#2 Get More Refcardz! visit refcardz.

com

CONTENTS INCLUDE:

Getting Started with Ajax


n
Getting to Know HTTP
n
Tips for Using XHR
n
Ajax and Architecture
n
Ajax Toolkits
n

n
Ajax User Interfaces
Hot Tips and more...
By Dave Crane

GETTING STARTED GETTING TO KNOW HTTP

The standard way to do Ajax is to use the XMLHttpRequest object, To make use of the XHR to its fullest, we recommend you
known as XHR by its friends. Use XHR directly, or via one of the become familiar with the workings of the HTTP protocol. Using
helpful Ajax libraries such as Prototype or jQuery. How do we use Ajax, you have much more control over HTTP than with classic
XHR “by hand”? To start with, we need to get a reference to it: web app development.
if (window.XMLHttpRequest) {
request
xhr = new XMLHttpRequest();
} else if (window.ActiveXObject) {
xhr = new ActiveXObject(“Microsoft.XMLHTTP”);
headers
}
We can then open a connection to a URL:
browser body
xhr.open(
“GET”,
“my-dynamic-content.jsp?id=”
+encodeURI(myId), server
true
);

Specify a callback function to receive the response: headers


www.dzone.com

body
xhr.onreadystatechange = function(){
response
processReqChange(req);
}
HTTP is a stateless request-response protocol.
and then send the request:
xhr.send(null); n
Both request and response contain headers and an optional
The server may be busy, or the network may be slow. We don’t want body, which is free text.
to sit around doing nothing until the response arrives, and because n
Only a POST request contains a body.
we’ve assigned the callback function, we don’t have to. That’s the
five-minute guide for the impatient. For those who like to know
n
A request defines a verb or method.
the details, we’ve listed the fuller details of the XHR object below. n
The Mime type of request and response can be set by the
header Content-type
Method Name Parameters and Descriptions

open(method, url, async) open a connection to a URL


method = HTTP verb (GET, POST, etc.) Not all Microsoft browsers rely on ActiveX.
url = url to open, may include querystring Hot
async = whether to make asynchronous request Tip IE7 provides a native JavaScript XHR, so we
check for that first.
onreadystatechange assign a function object as callback (similar to onclick,
Getting Started with Ajax

onload, etc. in browser event model)

setRequestHeader add a header to the HTTP request


(namevalue)

send(body) send the request Get More Refcardz


body = string to be used as request body
(They’re free!)
abort() stop the XHR from listening for the response
n Authoritative content
readyState stage in lifecycle of response (only populated after send()
is called) n Designed for developers
n Written by top experts
httpStatus The HTTP return code (integer, only populated after
response reaches the loaded state) n Latest tools & technologies

responseText body of response as a JavaScript string (only set after n Hot tips & examples
response reaches the interactive readyState)
n Bonus content online
responseXML body of the response as a XML document object (only
set after response reaches the interactive readyState) n New issue every 1-2 weeks

getResponseHeader read a response header by name


(name) Subscribe Now for FREE!
getAllResponseHeaders() Get an array of all response header names Refcardz.com

DZone, Inc. | www.dzone.com


2
Getting Started with Ajax
tech facts at your fingertips

Common HTTP Verbs Handling the Response


99% of the time, you’ll only need GET and POST. Many other We’ve assigned a callback handler function to our XHR object.
verbs are used by WebDAV, Subversion over HTTP, and other This function will get called several times as the response comes
niche applications, but not all web servers will understand them. in. Typically, we only want to parse the response once it has fully
arrived, i.e. the readyState is complete.
Verb Notes

GET Strictly speaking, should be used only to fetch data, not to effect xhr.onreadystatechange=function(){
changes on the server. GET requests contain no body. Parameters are if (xhr.readyState==4){
passed in the querystring of the URL. if (xhr.status==200){
POST Should be used to update data on the server. Parameters/data passed parseResponse(xhr);
in the body. }else{
//handle the HTTP error...
HEAD Will fetch the headers of the response only, not the body. Useful for
finding out how large a resource is (read the Content-length header) }
or how old it is (read the Last-modified header), for example. };
};
If you’re using the increasingly popular REST approach to web
services, the HTTP verb is used to indicate the type of operation XHR ReadyState Values
being performed. The most commonly used HTTP verbs in REST State Value Comments
map onto the CRUD (create, read, update, delete) approach:
0 Uninitialized The request hasn’t yet been sent
HTTP Verb CRUD Notes 1 Loading The response hasn’t yet arrived
operation
2 Loaded Response headers can be read
PUT Create Add a new object instance to the domain model.
3 Interactive Response body is incomplete, but can be read
GET Read Get an existing domain object from the server.
4 Complete Response body is complete
POST Update Modify an existing domain object.

DELETE Delete Remove an existing object from the domain model. So, what might the parseResponse() method look like? We have
a lot of freedom in the types of response we send. Let’s look at
Common Mime Types some of the common ones.
Setting the right mime type for your request and response is
good manners—it’s also vital to get the app to behave correctly! Handling a HTML Response
The server can send pre-assembled HTML content, which we
Mime Type Meaning Usage
just stitch into the web page.
application/x-www- Body is an encoded Sending request from HTML
form-urlencoded querystring of form or Ajax. Required in order <table class=’item selected’> function parseResponse(xhr){
key-value pairs for server to decode parameters <tr> var div=document
into $_GET, servlet parameters, or <td rowspan=’3’ valign=’top’><div .getElementById(“myDiv”);
HttpRequest.Form. class=’itemIcon’><img div.innerHTML=xhr.responseText;
src=’../images/kmoon.png’></div></td> }
text/xml, Body is an XML Can be used anywhere – request <td class=’itemTitle’>The Moon on a
application/xml document or response. Must set response to Stick</td>
</tr>
one of these in order to use XHR.
<tr>
responseXML property.
<td valign=’top’>What every project
manager wants - and they want it
text/plain Body is plain
yesterday!<br/><br/><i>NB: Stick not
unformatted text included.</i></td>
</tr>
text/html, text/xhtml Body is (X)HTML Standard web pages sent from
<tr>
content server, or content fragments sent to <td><div class=’price’>$365.00</div></td>
Ajax apps. </tr>
</tr>
text/javascript Body is a piece of Standard .js files, JavaScript </table>
JavaScript code fragments sent to Ajax apps.

image/png, image/ Body is a binary Images sent by server.


jpeg, image/gif image Handling a JSON Response
JSON is a simple text-markup that’s extremely easy for JavaScript
to digest! It doesn’t come so naturally to server-side languages,
TIPS FOR USING XHR
but there are JSON libraries for most servers these days—see
http://www.json.org. Most Ajax libraries now provide support
n
Always set async to true when calling open(). Synchronous Ajax
for JSON.
requests block the browser UI, giving the stop-start behaviour
we were trying to get away from in the first place! { function parseResponse(xhr){
imgSrc: “kmoon.png”, var jsonObj=eval(
n
XHR can be fussy about order of setting-up. Always set the title: “The Moon on a Stick”, “(“
description: “What every proj- +xhr.responseText
callback handler before calling send() ect manager wants - and they want it +”)”
yesterday!<br/><br/><i>NB: Stick not );
n
To send HTML-form like data included.</i>”, setImgSrc(jsonObj.imgSrc);
n
Use encodeURI() to encode all data values price: “365.00” setTitle(jsonObj.title);
} }

Set the mime-type of the request to application/x-www-
n


form-urlencoded
n
Set the response mime type to application/xml or text/xml if
you want to use the responseXML property

DZone, Inc. | www.dzone.com


3
Getting Started with Ajax
tech facts at your fingertips

TIPS FOR USING XHR, continued AJAX AND ARCHITECTURE

Handling an XML Response Does Ajax only affect the client-side? Certainly not! Particularly
XML is a more natural fit for most server technologies. XHR sup- if your server is responding with data rather than HTML frag-
ports XML by giving us the responseXML property, but parsing ments, you’ll want to refactor to some extent.
this using the DOM is hard work.
dumb client thin client thick client
<item imgSrc=”kmoon.png” function parseResponse(xhr){
price=”365.00”> var xmlDoc=xhr.responseXML;
browser browser browser
<title>The Moon on a var item=xmlDoc.getElementsByTagName
Stick</title> (‘item’)[0]; display display display
<description><![CDATA[What var imgSrc=item.getAttribute
presentation presentation
every project manager wants - (‘imgSrc’);
and they want it var title=item.getElementsByTagName business objects
yesterday!<br/><br/><i>NB: Stick (‘title’)[0]
data transfer
not .firstChild.data;
included.</i>]]></description> setImgSrc(imgSrc);
</item> setTitle(title);
} presentation
presentation data transfer
business objects business objects business objects
Some browsers also support XPath as a more pleasant way to
parse XML. Sarissa and mozXPath.js both provide cross-browser
XPath support.
persistence persistence persistence

<item imgSrc=”kmoon.png” function parseResponse(xhr){


price=”365.00”> var xmlDoc=xhr.responseXML; web server web server web server
<title>The Moon on a var imgSrc=xmlDoc.selectSingleNode
Stick</title> (‘/item/@imgSrc’).value;
<description><![CDATA[What var title=xmlDoc.selectSingleNode database server database server database server
every project manager wants - (‘/item/title/text()’).value;
and they want it setImgSrc(imgSrc);
yesterday!<br/><br/><i>NB: Stick setTitle(title);
not } Dumb client and thick client above are extremes. In between,
included.</i>]]></description>
</item>
there is a thinner (but still intelligent) client, that will suffice in
many cases. No single model is right for all cases. Try out these
rules of thumb:
Handling a Javascript Response
Another approach to Ajax is to generate scripts on the server, n
To add small Ajax features to an existing app, stick with the thin
and send them to the client to be evaluated. Care should be client approach. Thick client is for complex, line-of-business
taken here to define a suitably high-level API on the client app replacements.
against which the generated script is to run, otherwise tight n
Your client-side code is visible, and runs on somebody else’s
coupling between server and client code can result. machine. Don’t expose details of your business tier. Keep it
setImgSrc(“kmoon.png”); function parseResponse(xhr){ coarse-grained.
setTitle( eval(xhr.responseText);
“The Moon on a Stick” } n
Some functionality MUST be kept on the server, such as data
);
validation. Simple, fast validation on the client is an addition,
not a replacement!
Handling Mixed Responses n
Treat your client-side code well. Use the patterns and practises
Some Javascript libraries allow mixing of these dialects of
that you would use on the server to keep your code clean and
Ajax within a single response. The Prototype Ajax.Updater, for
maintainable.
example, can accept a response as HTML, into which <script>
tags are embedded. The script will be extracted and evalu- n
Most projects have a legacy system behind them. How can you
ated, while the rest of the content is embedded into a target introduce Ajax with minimal disruption? Does it speak XML, or
DOM element. generate HTML from components? Can you re-use that?

AJAX TOOLKITS continued on next page...

Toolkits and frameworks will make your life easier in Client-side versus Server-side
several ways: Some toolkits are JavaScript-only, others include a back-end

Providing tried-and-tested solutions to common
n system too. Client-side toolkits will give more flexibility, but may
problems require more work on the server-side too.

Abstracting away cross-browser incompatibilities and
n
High-level versus Low-level
annoyances JavaScript is a flexible language, and some toolkits are geared

Providing higher level abstractions such as ready-made
n
towards enhancing the language itself in a variety of ways. Oth-
UI widgets and networking stacks ers are more concerned with higher-level issues such as simplify-
However, it’s a jungle out there, with many different types of ing XHR, or providing drop-in widgets such as trees, tables and
toolkits on the market. Let’s divide them into broad families. drag-and-drop.

DZone, Inc. | www.dzone.com


4
Getting Started with Ajax
tech facts at your fingertips

Some popular Ajax Toolkits Loading HTML Content into a DOM Node
Name Client/ High/ Comments Prototype jQuery
Server Low-level
new Ajax.Updater( $(“#myDomNode”).load(
Prototype Client Low Remodels and extends $(“myDomNode”), “my-dynamic-content.jsp”,
“my-dynamic-content.jsp”, { id: myId }
(http://prototypejs.org) JavaScript following the Ruby
{ method: “post”, );
scripting language. Many
params: { id: myId }
features for arrays, functions, }
XHR, DOM and forms. );
Scriptaculous Client High Special effects, drag and
(http://script.aculo.us) drop, and widgets built on
n
No need to provide a callback function at all
top of prototype.
Working wth JSON Responses
dojo Client Low-high Comprehensive set of
(http://dojotoolkit.org) libraries covering everything Prototype jQuery
from packaging & language
features through Ajax to UI new Ajax.Request( $.getJSON(
“my-dynamic-content.jsp”, “my-dynamic-content.jsp?id=”+myId,
widgets.
{ method: “post”, function(json){
Yahoo User Interface (YUI) Client Low-high Another comprehensive set params: { id: myId }, alert(json.someProperty);
(http://developer.yahoo.com/ of libraries covering many onComplete: }
yui/) aspects of Ajax development. function(response,json){ );
alert(json.someProperty);
Ext Client High Widget-based set of user }
(http://extjs.com) interface components with }
Ajax support. );

sarissa Client Low Rich library for working n


JSON response returned to our callback already parsed
(http://sarissa.sf.net) with XML, providing cross-
browser XPath and XSLT.

Mochikit Client Low-high General-purpose Ajax and


GENERAL JAVASCRIPT PROGRAMMING TIPS
(http://mochikit.com) DHTML library, inspired by
Python. JavaScript is a loosely-typed scripting language with support for
jQuery Client Low Small, concise Ajax and object-oriented and functional programming styles. Although it
(http://jquery.com) DOM helper library. looks like Java and C-family languages, it’s quite different under
MooTools Client Low-high Modular library covering the hood. Here are a few survival tips to get you through your first
(http://mootools.net) everything from core serious encounter with this language:
classes to special effects. A
promising newcomer. n
Objects can be extended at runtime with new properties.

Ruby on Rails Server Low-high Primarily a server-side toolkit, Think of Javascript objects as associative arrays.
(http://www.rubyonrails.org) but has first-rate support
for Ajax, using Prototype
n
Functions are first-class objects, and can be passed as

and Scriptaculous. Allows arguments into other functions (see the numerous callback
large parts of the client tier functions earlier).
to be written on the server,
in Ruby. n
JavaScript functions support closures. That is, variables that

GWT Client High Java framework that allows are in scope when a function is defined can still be referenced
(http://code.google.com/ Ajax client tier to be written inside the function, even if it is invoked later.
webtoolkit) in Java.

JSF Server High Various JSF vendors have


(various vendors) Ajax-enabled some of their AJAX USER INTERFACES
components, again allowing
some Ajax functionality
without hand-writing Before Ajax, the UI was nearly always delivered as declarative
JavaScript. HTML, and the Document Object Model, or DOM, was only used
in moderation. With Ajax—especially single-page applications—
We haven’t time to show you how to make Ajax calls with all of the DOM can play a much bigger role.
these toolkits, but let’s pick two of the most popular: Prototype
Working with the DOM is a two-stage process:
and jQuery.
n Finding the elements we want to work with
The Basics : Making an Ajax request n Modifying their contents or reorganizing them

Prototype jQuery Finding DOM Elements


new Ajax.Request( $.post( The DOM standard itself gives us a few basic tools to work with.
“my-dynamic-content.jsp”, “my-dynamic-content.jsp”,
{ method: “post”,
Enterprising JavaScript library developers have built on top of
{ id: myId },
params: { id: myId }, function(xhr){ these to provide a much richer set of functionality.
onComplete: function(response){
parseResponse(xhr);
parseResponse(response); Function arguments returns notes
}
}
} );
document. string DOM find single element on
); getElementById() Element page. Id attribute must be
unique in page
n
No need to create your own XHR object
document. string collection find all elements on page
n
Use high-level, meaningful callbacks rather than getElementsByTagName() of DOM of a particular HTML tag
onreadystatechange element.
elements type e.g. H1, IMG, LI. Use
as a method of element
n
Sensible defaults provided for all the options you don’t want getElementsByTagName()
to search a subtree of the
to specify yourself document

DZone, Inc. | www.dzone.com


5
Getting Started with Ajax
tech facts at your fingertips

Finding DOM Elements, continued Modifying the DOM


Function arguments returns notes
Again, the DOM standard gives us a basic set of tools to work with,
and browser vendors have effectively standardized a few more.
element.childNodes none collection find node’s immediate
of DOM children
Function arguments returns notes
elements
element.parentNode none DOM find node’s immediate document. string (tag DOM create new content slowly and
Element parent createElement() name) Element painfully!

element.nextSibling none DOM allow


element.previousSibling Element traversal of sibling nodes document. string DOM text
createTextNode() (content of node
The id attribute is often too specific—adding one to each element we node)

may need to locate becomes tedious, and clutters the markup. Tag element. n/a n/a use the browser’s built-in HTML
names, on the other hand, are not specific enough to be useful in innerHTML parser to shortcut the creation
many cases. The most common solution is to use CSS classes to lo- of new content

cate elements. We can make these as specific or general as we need. element. DOM null add a DOM node as child of
appendChild() element another node
Finding DOM elements using Prototype element. DOM null remove a child DOM node from
removeChild() element the parent
Function arguments returns notes
element. DOM null add a DOM node in relation to
$() string, DOM powerful and
insertBefore() element other siblings, not just at the end
many element, concise superset of
strings, or or array of getElementById()
elements elements Modifying the DOM with Prototype
document. string (a array of version 1.5+ Prototype favors the use of innerHTML to modify the DOM. It
getElementsByClassName() CSS class) DOM simple analogue to enhances this with the Insertion namespace, and, more recently,
element. elements getElementsByTagName()
getElementsByClassName() an insert method on the DOM element class itself.
$$() string array of version 1.5+
Function arguments notes
(selector DOM accepts CSS selector
rule) elements rules, and xpath queries
Insertion.Top DOM element, version 1.5: Object that inserts
element.select() string array of version 1.6 Insertion.Bottom string (HTML content) HTML content into element
(selector DOM analogue to $$(), Insertion.Before alongside existing content.
rule) elements syntactically neater Insertion.After
element.up() selector DOM powerful positional Element.update() string (HTML content) version 1.6: overwrites content in
element.down() rules, Element navigation methods, element
counts that can work with
element.next()
(both selectors Element.insert() HTML content or hash version 1.6: Can insert a single
element.previous() optional) of content piece of content, or multiple
pieces in one go
Examples
Element.remove() none all versions: removes the calling
$(“myList”)  selects the element with id=myList element (and its children) from
.select (“li.new”)  selects all DOM elements of type the page
<LI> with CSS class new within
subtree beneath myList Prototype provides no support for building DOM elements
$(“widget”)  selects element with id=”widget” programmatically, but the Scriptaculous library adds a DOMBuilder
.down(“img div.handle”,2)  internally returns list of all <IMG> object to the mix.
tags that are children of a DIV with
CSS class handle, and returns the Modifying the DOM with jQuery
second one jQuery is based around selecting sets of DOM elements, and it
provides methods for manipulating sets of DOM elements in bulk.
Finding DOM elements using jQuery (These can be used on sets of one element too!) The methods here
Function arguments returns notes all operate on a set of DOM nodes returned from a selector.
$() string jQuery although only one method is listed here,
(selector object jQuery is exceptionally powerful in this Function arguments notes
rule) wrapping regard. The selector rules encompass CSS3, $.html() string (HTML simple wrapper around innerHTML, will
array of xpath (optional) and a range of custom content) duplicate content for each element in the set
elements selectors too!
$.append() string (HTML insert content into node(s) alongside existing
Examples $.prepend() content) content
$.before()
$(“div”)  select all nodes by tag type $.after()
$(“#myList”)  select by unique id
$.appendTo() string argument is the target element or elements,
$(“ul#myList li.new”)  complex CSS selector $.prependTo() (selector rule) to which the current node will be moved to. If
$.insertBefore() or DOM multiple targets are present, the nodes being
$.insertAfter() element appended will be copied to each one

DOM elements can be assigned to multiple CSS classes. $.remove() none remove all elements in set from the page
Hot When finding elements using a selector mechanism, you
Tip $.empty() none empty all elements in the set of their content
may use the same CSS classes that determine the look of $.wrap() string (HTML) or wrap each element in set individually with a
your page, or you may assign separate marker classes, DOM element copy of the content provided in argument

i.e. CSS classes that have no visual effect on the page. $.wrapAll() string (HTML) or wrap all elements in the set as a single unit with
DOM element the content provided in argument

DZone, Inc. | www.dzone.com


6
Getting Started with Ajax
tech facts at your fingertips

FireBug FF www.getfirebug.com Swiss army knife for developers,


WIDGETS VS. BEHAVIORS incorporating DOM & CSS
inspector, interactive debugger,
network monitor and profiler.
Both jQuery and Prototype (and its sister Scriptaculous) tend Web IE searchmicrosoft.com Closest thing to Firebug for IE,
towards a style of UI called Unobtrusive Javascript, in which the Developers minus the debugger.
Toolkit
content of the page is declared as HTML, and subsequently made
Script IE searchmicrosoft.com Free Javascript debugger for
interactive. Selectors play an important role in this approach, in Debugger IE, (also check out Visual Studio
locating the elements to which to add behavior. There is an alterna- express’ debugger).

tive approach to developing Ajax UIs, much more akin to desktop Fiddler IE/any www.fiddlertool.com Powerful network monitor with
programmable interface for
application development, in which the DOM elements are created modifying requests in many
programmatically by javascript components, which the designer ways. Tight integration with IE,
but can work with any browser.
then wires together using layouts and containers. Qooxdoo and
LiveHTTP FF livehttpheaders.mozdev.org Network monitor extension for
Ext2 are both examples of this style of UI development. Headers Firefox.

JSUnit any www.jsunit.net The original unit testing


framework for Javascript.
TOOLS OF THE TRADE
Selenium FF/any www.openqa.org Powerful unit testing tool for
Javascript, featuring interactive
In an ideal world, choosing the right framework makes develop- test recorder IDE (Firefox only)
and browser automation tool
ment a breeze, but in practice, you’ll need to go under the hood (most browsers).
from time to time to figure out what’s going on. We recommend YSlow FF developer.yahoo.com/yslow Comprehensive performance
the following tools to keep your Ajax development on track. analysis for web pages, runs as
a plugin to Firebug!

Tamper Data FF http://addons.mozilla.org/ Use tamperdata to view and


en-US/firefox/addon/966 modify HTTP/HTTPS headers
and post parameters.

ABOUT THE AUTHOR RECOMMENDED BOOK


Dave Crane Ajax in Action explains how
Dave Crane has over ten years experience in the IT industry, working with J2EE, to distribute the application
PHP, Ajax, and a variety of scripting languages in industries including home between the client and the
entertainment, banking, simulation modelling and global supply chains. He server (hint: use a “nested MVC”
currently works as Developer/Architect for Historic Futures Ltd., and runs Ajax design) while retaining the
training courses in the UK and overseas with Skillsmatter Ltd. He is well-known integrity of the system. You will
as the author of Manning’s Ajax in Action, Prototype & Scriptaculous in Action learn how to ensure your app is
and Ajax in Practice. flexible and maintainable,
and how good, structured design can help avoid
Publications problems like browser incompatibilities.
n Ajax in Action
n Prototype & Scriptaculous in Action BUY NOW
n Ajax in Practice books.dzone.com/books/ajax-in-action

Get More FREE Refcardz. Visit refcardz.com now!


Upcoming Refcardz: Available:
Core Seam Essential Ruby JavaServer Faces
Core CSS: Part III Essential MySQL Core CSS: Part I
JUnit and EasyMock Struts2
Hibernate Search
Getting Started with MyEclipse Core .NET
FREE
Equinox Spring Annotations Very First Steps in Flex
EMF Core Java C#
Core CSS: Part II Groovy
XML
PHP NetBeans IDE 6.1 Java Editor
JSP Expression Language Getting Started with JPA RSS and Atom
Design Patterns
ALM Best Practices Visit refcardz.com for a complete listing of available Refcardz. Published June 2008

DZone, Inc.
ISBN-13: 978-1-934238-02-8
1251 NW Maynard
ISBN-10: 1-934238-02-3
Cary, NC 27513
50795
888.678.0399
DZone communities deliver over 4 million pages each month to
919.678.0300
more than 1.7 million software developers, architects and decision
Refcardz Feedback Welcome
makers. DZone offers something for everyone, including news, refcardz@dzone.com
$7.95

tutorials, cheatsheets, blogs, feature articles, source code and more. Sponsorship Opportunities 9 781934 238028
“DZone is a developer’s dream,” says PC Magazine. sales@dzone.com

Copyright © 2008 DZone, Inc. All rights reserved. No part of this publication may be reproduced, stored in a retrieval system, or transmitted, in any form or by means electronic, Version 1.1
mechanical, photocopying, or otherwise, without prior written permission of the publisher.

You might also like