<!--#include virtual="commontop.html" -->
<title>Web Programming Step by Step, Lecture 17: Ajax</title>
</head>
<body>
<div class="layout">
<div id="controls"><!-- DO NOT EDIT --></div>
<div id="currentSlide"><!-- DO NOT EDIT --></div>
<div id="header"></div>
<div id="footer">
<h1><em>Web Programming Step by Step</em>, Lecture 17</h1>
<h2>Ajax</h2>
</div>
</div>
<div class="presentation">
<div class="slide">
<h1><a href="http://www.webstepbook.com/">Web Programming Step by Step</a></h1>
<h3>Lecture 17 <br /> Ajax</h3>
<h4>Reading: 10.1 - 10.2</h4>
<p class="license">
Except where otherwise noted, the contents of this presentation are Copyright 2010 Marty Stepp and Jessica Miller.
</p>
<div class="w3c">
<a href="http://validator.w3.org/check/referer"><img src="images/w3c-xhtml11.png" alt="Valid XHTML 1.1" /></a>
<a href="http://jigsaw.w3.org/css-validator/check/referer"><img src="images/w3c-css.png" alt="Valid CSS!" /></a>
</div>
</div>
<div class="slide">
<h1>
Synchronous web communication
<span class="readingsection">(10.1)</span>
</h1>
<div class="centerfigure">
<img src="images/figure_1_synchronous.png" alt="synchronous communication" style="width: 60%;" />
</div>
<ul>
<li><span class="term">synchronous</span>: user must wait while new pages load
<ul>
<li>
the typical communication pattern used in web pages (click, wait, refresh)
</li>
</ul>
</li>
</ul>
</div>
<div class="slide">
<h1><a href="http://en.wikipedia.org/wiki/Web_application">Web applications</a> and Ajax</h1>
<div class="rightfigure">
<img src="images/ajax_bleach.gif" alt="Ajax bleach" />
</div>
<ul>
<li>
<span class="term">web application</span>: a dynamic web site that mimics the feel of a desktop app
<ul>
<li>
presents a continuous user experience rather than disjoint pages
</li>
<li>
examples:
<a href="http://mail.google.com/">Gmail</a>,
<a href="http://maps.google.com/">Google Maps</a>,
<a href="http://docs.google.com/">Google Docs and Spreadsheets</a>,
<a href="http://www.flickr.com/">Flickr</a>,
<a href="http://www.a9.com/">A9</a>
</li>
</ul>
</li>
<li>
<span class="term">Ajax</span>: Asynchronous JavaScript and XML
<ul>
<li>not a programming language; a particular way of using JavaScript</li>
<li>downloads data from a server in the background</li>
<li>allows dynamically updating a page without making the user wait</li>
<li>avoids the "click-wait-refresh" pattern</li>
<li>
examples: UW's <a href="http://www.cs.washington.edu/education/courses/cse143/09wi/diff.html">CSE 14x Diff Tool</a>, <a href="http://webster.cs.washington.edu:8080/practiceit/">Practice-It</a>;
<a href="http://suggest.google.com/">Google Suggest</a>
</li>
</ul>
</li>
</div>
<div class="slide">
<h1>Asynchronous web communication</h1>
<div class="centerfigure">
<img src="images/figure_2_asynchronous.png" alt="synchronous communication" style="width: 60%;" />
</div>
<ul>
<li><span class="term">asynchronous</span>: user can keep interacting with page while data loads
<ul>
<li>
communication pattern made possible by Ajax
</li>
</ul>
</li>
</ul>
</div>
<div class="slide">
<h1><a href="http://www.w3schools.com/XML/xml_http.asp"><code>XMLHttpRequest</code></a> (and why we won't use it)</h1>
<ul>
<li>JavaScript includes an <code>XMLHttpRequest</code> object that can fetch files from a web server
<ul>
<li>supported in IE5+, Safari, Firefox, Opera, Chrome, etc. (with minor compatibilities)</li>
</ul>
</li>
<!--
Internet Explorer uses an ActiveXObject, while other browsers uses the built-in JavaScript object called XMLHttpRequest.
-->
<li>it can do this <span class="term">asynchronously</span> (in the background, transparent to user)</li>
<li>the contents of the fetched file can be put into current web page using the DOM</li>
<li style="margin-top: 2em">sounds great!...</li>
<li class="incremental">... but it is clunky to use, and has various browser incompatibilities</li>
<li class="incremental">Prototype provides a better wrapper for Ajax, so we will use that instead</li>
</ul>
</div>
<div class="slide">
<h1>A typical Ajax request</h1>
<div class="rightfigure">
<img src="images/ajax_request.png" alt="request" style="width: 100%" />
</div>
<ol class="compressed">
<li>user clicks, invoking an event handler</li>
<li class="incremental">handler's code creates an <code>XMLHttpRequest</code> object</li>
<li class="incremental"><code>XMLHttpRequest</code> object requests page from server</li>
<li class="incremental">server retrieves appropriate data, sends it back</li>
<li class="incremental"><code>XMLHttpRequest</code> fires an event when data arrives
<ul>
<li>this is often called a <span class="term">callback</span></li>
<li>you can attach a handler function to this event</li>
</ul>
</li>
<li class="incremental">your callback event handler processes the data and displays it</li>
</ol>
</div>
<div class="slide">
<h1>
Prototype's Ajax model
<span class="readingsection">(10.2.4)</span>
</h1>
<pre class="syntaxtemplate js">
new Ajax.Request("<var>url</var>",
{
<var>option</var> : <var>value</var>,
<var>option</var> : <var>value</var>,
...
<var>option</var> : <var>value</var>
}
);
</pre>
<ul>
<li>construct a Prototype <code>Ajax.Request</code> object to request a page from a server using Ajax</li>
<li>constructor accepts 2 parameters:
<ol>
<li>the <strong>URL</strong> to fetch, as a String,</li>
<li>
a set of <a class="popup" href="http://prototypejs.org/api/ajax/options"><strong>options</strong></a>, as an array of <var>key</var> : <var>value</var> pairs in <code>{}</code> braces
<span class="aside">(an anonymous JS object)</span>
</li>
</ol>
</li>
<li>hides icky details from the raw <code>XMLHttpRequest</code>; works well in all browsers</li>
</ul>
</div>
<div class="slide">
<h1>Prototype Ajax options</h1>
<table class="standard">
<tr>
<th>option</th>
<th>description</th>
</tr>
<tr>
<td>
<code>method</code>
</td>
<td>
how to fetch the request from the server (default <code>"post"</code>)
</td>
</tr>
<tr>
<td>
<code>parameters</code>
</td>
<td>
query parameters to pass to the server, if any (as a string or object)
</td>
</tr>
<tr>
<td>
<code>asynchronous</code>
</td>
<td>
should request be sent asynchronously in the background? (default <code>true</code>)
</td>
</tr>
<tr>
<td colspan="2" style="font-size: smaller;">
others: <code>contentType</code>, <code>encoding</code>,
<code>requestHeaders</code>
</td>
</tr>
</table>
<pre class="syntaxtemplate js">
new Ajax.Request("http://www.example.com/foo/bar.txt",
{
<em>method: "get",
parameters: {name: "Ed Smith", age: 29},</em> <span class="comment">// "name=Ed+Smith&age=29"</span>
<var>...</var>
}
);
</pre>
</div>
<div class="slide">
<h1>Prototype Ajax event options</h1>
<table class="standard">
<tr>
<th>event</th>
<th>description</th>
</tr>
<tr>
<td>
<code>onSuccess</code></strong>
</td>
<td>
request completed successfully
</td>
</tr>
<tr>
<td>
<code>onFailure</code></strong>
</td>
<td>
request was unsuccessful
</td>
</tr>
<tr>
<td>
<code>onException</code></strong>
</td>
<td>
request has a syntax error, security error, etc.
</td>
</tr>
<tr>
<td colspan="2" style="font-size: smaller;">
others: <code>onCreate</code>, <code>onComplete</code>,
<code>on###</code> (for HTTP error code ###)
</td>
</tr>
</table>
<pre class="syntaxtemplate js">
new Ajax.Request("http://www.example.com/foo.php",
{
parameters: {password: "abcdef"}, <span class="comment">// "password=abcdef"</span>
<em>onSuccess: mySuccessFunction</em>
}
);
</pre>
</div>
<div class="slide">
<h1>Basic Prototype Ajax template</h1>
<pre class="syntaxtemplate js">
new Ajax.Request("<var>url</var>",
{
method: "get",
onSuccess: <var>functionName</var>
}
);
...
function <var>functionName</var>(<em>ajax</em>) {
<var>do something with <em>ajax.responseText</em></var>;
}
</pre>
<ul>
<li>attach a handler to the request's <code>onSuccess</code> event</li>
<li>the handler takes an <a href="http://www.prototypejs.org/api/ajax/response">Ajax response object</a>, which we'll name <code>ajax</code>, as a parameter</li>
</ul>
</div>
<div class="slide">
<h1><a href="http://www.prototypejs.org/api/ajax/response">Ajax response</a> object's properties</h1>
<table class="standard">
<tr>
<th>property</th>
<th>description</th>
</tr>
<tr>
<td>
<code>status</code>
</td>
<td>
the request's HTTP error code (200 = OK, etc.)
</td>
</tr>
<tr>
<td>
<code>statusText</code>
</td>
<td>
HTTP error code text
</td>
</tr>
<tr>
<td>
<code>responseText</code>
</td>
<td>
the entire text of the fetched file, as a <code>String</code>
</td>
</tr>
<tr>
<td>
<code>responseXML</code>
</td>
<td>
the entire contents of the fetched file, as a DOM tree (seen later)
</td>
</tr>
</table>
<pre class="examplecode js">
function handleRequest(ajax) {
alert(<em>ajax.responseText</em>);
}
</pre>
<ul>
<li>most commonly used property is <code>responseText</code>, to access the fetched text content</li>
</ul>
</div>
<div class="slide">
<h1>
<code>XMLHttpRequest</code> security restrictions
</h1>
<div class="centerfigure">
<img src="images/ajax_security_error.png" alt="Ajax security error" />
</div>
<ul>
<li>cannot be run from a web page stored on your hard drive</li>
<li>can only be run on a web page stored on a web server</li>
<li>can only fetch files from the same server that the page is on
<ul>
<li><code>http://www.foo.com/a/b/c.html</code> can only connect to <code>www.foo.com</code></li>
</ul>
</li>
</ul>
</div>
<div class="slide">
<h1>Handling Ajax errors</h1>
<pre class="syntaxtemplate js">
new Ajax.Request("<var>url</var>",
{
method: "get",
onSuccess: <var>functionName</var>,
<em>onFailure: ajaxFailure</em>,
<em>onException: ajaxFailure</em>
}
);
...
<em>function ajaxFailure(ajax, exception) {</em>
alert("Error making Ajax request:" +
"\n\nServer status:\n" + ajax.status + " " + ajax.statusText +
"\n\nServer response text:\n" + ajax.responseText);
if (exception) {
throw exception;
}
}
</pre>
<ul>
<li>for user's (and developer's) benefit, show an error message if a request fails</li>
</ul>
</div>
<div class="slide">
<h1>Debugging Ajax code</h1>
<div class="centerfigure">
<img src="images/firebug_ajax.png" alt="Firebug Ajax" style="max-width: 70%;" />
</div>
<ul>
<li><strong>Net</strong> tab shows each request, its parameters, response, any errors</li>
<li>expand a request with <span class="term" style="border: 1px solid black;">+</span> and look at <span class="term">Response</span> tab to see Ajax result</li>
</ul>
</div>
<div class="slide">
<h1>Creating a <code>POST</code> request</h1>
<pre class="syntaxtemplate js">
new Ajax.Request("<var>url</var>",
{
<em>method: "post",</em> <span class="comment">// optional</span>
<em>parameters: { <var>name</var>: <var>value</var>, <var>name</var>: <var>value</var>, ..., <var>name</var>: <var>value</var> },</em>
onSuccess: <var>functionName</var>,
onFailure: <var>functionName</var>,
onException: <var>functionName</var>
}
);
</pre>
<ul>
<li><code>method</code> should be changed to <code>"post"</code> (or omitted; <code>post</code> is default)</li>
<li>any query parameters should be passed as a <code>parameters</code> parameter
<ul>
<li>written between <code>{}</code> braces as a set of <var>name</var> : <var>value</var> pairs <span class="aside">(another anonymous object)</span></li>
<li><code>get</code> request parameters can also be passed this way, if you like</li>
</ul>
</li>
</ul>
</div>
<div class="slide">
<h1>Prototype's Ajax Updater</h1>
<pre class="syntaxtemplate js">
new Ajax.Updater("<var>id</var>", "<var>url</var>",
{
method: "get"
}
);
</pre>
<hr />
<ul>
<li><a href="http://www.prototypejs.org/api/ajax/updater"><code>Ajax.Updater</code></a> fetches a file and injects its content into an element as <code>innerHTML</code></li>
<li>additional (1st) parameter specifies the <code>id</code> of element to inject into</li>
<li><code>onSuccess</code> handler not needed (but <code>onFailure</code>, <code>onException</code> handlers may still be useful)</li>
</ul>
</div>
<div class="slide">
<h1>PeriodicalUpdater</h1>
<pre class="syntaxtemplate js">
new Ajax.PeriodicalUpdater("<var>id</var>", "<var>url</var>",
{
frequency: <var>seconds</var>,
<var>name</var>: <var>value</var>, ...
}
);
</pre>
<hr />
<ul>
<li><a href="http://www.prototypejs.org/api/ajax/periodicalupdater"><code>Ajax.PeriodicalUpdater</code></a> repeatedly fetches a file at a given interval and injects its content into an element as <code>innerHTML</code></li>
<li><code>onSuccess</code> handler not needed (but <code>onFailure</code>, <code>onException</code> handlers may still be useful)</li>
</ul>
</div>
<div class="slide">
<h1>Ajax.Responders</h1>
<pre class="syntaxtemplate js">
Ajax.Responders.register(
{
on<var>Event</var>: <var>functionName</var>,
on<var>Event</var>: <var>functionName</var>,
...
}
);
</pre>
<hr />
<ul>
<li>sets up a default handler for a given kind of event for all Ajax requests</li>
<li>useful for attaching a common failure/exception handler to all requests in one place</li>
</ul>
</div>
<!--#include virtual="commonbottom.html" -->