In the previous chapters, especially Chapters 6 and 7, I concentrated on showing you how
to make web service requests using server-side languages such as PHP and Python. In
this section, I will show you how to make HTTP requests from JavaScript in the browser. The
key piece of technology is the XMLHttpRequest
(XHR) object (or XHR-like
objects in Internet Explorer). I will outline the basics of XHR, covering briefly how to
use XHR in the raw and then in the form of a library (specifically the YUI Connection
Manager) that abstracts the details of XHR for you.
The XHR object is an API for JavaScript for transferring XML and other textual data between the (client-side) browser and a server. There are differences in naming the object between Internet Explorer and the other browsers. Moreover, there are subtle issues that are easiest to handle by using a good wrapper around XHR, such as the Yahoo! Connection Manager.
Even though we will be using the Yahoo! Connection Manager to access XHR, it’s
still useful to look at how to use XHR before relying on a library. Drawing from
Peter-Paul Koch’s description of XHR at http://www.quirksmode.org/js/xmlhttp.html
and noting that the
following proxies an RSS feed of weather in the 94720 ZIP code (see the discussion after
the code for an explanation of the script) . . .
http://examples.mashupguide.net/ch10/weather.php?p=94720
then I present the following, which shows a typical usage of XHR to read the RSS feed:
http://examples.mashupguide.net/ch10/xhr.html
This extracts and displays an HTML excerpt from the feed:
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <title>xhr.html</title> <meta ?http-?equiv="content-type" content="text/html; charset=utf-8" > <script type="text/javascript"> //<![CDATA[ // based on http://www.quirksmode.org/js/xmlhttp.html var XMLHttpFactories = [ function () { xhr = new XMLHttpRequest(); xhr.overrideMimeType('text/xml'); return xhr; }, function () {return new ActiveXObject("Msxml2.XMLHTTP")}, function () {return new ActiveXObject("Msxml3.XMLHTTP")}, function () {return new ActiveXObject("Microsoft.XMLHTTP")} ]; function getXmlHttpRequest() { var xmlhttp = false; for (var i=0;i<XMLHttpFactories.length;i++) { try { xmlhttp = XMLHttpFactories[i](); } catch (e) { continue; } break; } return xmlhttp; } function writeResults() { if (xmlhttp.readyState == 4 && xmlhttp.status == 200) { resultsDiv = document.getElementById('results'); //alert(xmlhttp.responseText); var response = xmlhttp.responseXML; resultsDiv.innerHTML = response.getElementsByTagName('description')[1].firstChild.nodeValue; } } function load() { // http://examples.mashupguide.net/ch10/weather.php?p=94720 xmlhttp = getXmlHttpRequest(); if (xmlhttp) { zip = "94720"; url = "weather.php?p=" + zip; xmlhttp.open('GET', url, true); xmlhttp.onreadystatechange = writeResults; xmlhttp.send(null); } } //]]> </script> </head> <body onload="load()" > <!-- retrieve --> <div id="results"></div> </body> </html>
Note the following:
The code attempts to instantiate XHR by trying various ways to do so until it succeeds—or finally fails if none of the methods works.
Through the use of the following:
xmlhttp.onreadystatechange = writeResults;
the writeResults()
method is the callback for the HTTP GET
request. That is, XHR feeds writeResults
with its state (xmlhttp.readyState
). A typical usage pattern is for the callback routine to wait until the call is complete (xmlhttp.readyState == 4
) and for the return of an HTTP response code of 200 (to indicate a successful call).
xmlhttp.responseXML
returns the body of the HTTP response in the form of an XML DOM.
The main goal of this section is to again use JavaScript to call the Flickr API to get photos from a given bounding box. In the previous section, you learned how to use XHR directly; here, I show you how to use a library that wraps XHR: the Yahoo! UI (YUI) Library’s Connection Manager, which is documented here:
http://developer.yahoo.com/yui/connection/
The official examples page for the Connection Manager is here:
http://developer.yahoo.com/yui/examples/connection/index.html
Let’s look at the weather example provided by the YUI:
http://developer.yahoo.com/yui/examples/connection/weather.html
Our ultimate goal is to use the Connection Manager to hook up the Flickr API. Instead of jumping directly to that goal, I’ll first explain the weather example. The server-side part is relatively easy to understand, thus letting you concentrate on the XHR part of the example. The example is built in with the YUI download, and therefore you can immediately see an example of a client-side JavaScript invocation of the Yahoo! weather web service.
Enter a ZIP code, and hit Get Weather RSS. The web page uses XHR (wrapped by the Connection Manager) to retrieve an RSS 2.0 feed for the ZIP code, parses the weather information, and displays it on the page. Note that this happens without a page reload—remember that is what XHR (and Ajax) can do for you.
One thing to notice about weather.html
is that its JavaScript code invokes assets/weather.php
running from the same server. That is, if you have a version of the YUI example loaded on examples.
?mashupguide.net
:
http://examples.mashupguide.net/lib/yui/examples/connection/weather.html
you’ll see that it calls the following:
http://examples.mashupguide.net/lib/yui/examples/connection/assets/weather.php
What does weather.php
do?
A quick study shows that weather.php
takes the ZIP code (that is, 94720), does an HTTP GET
request on the Yahoo! Weather API (http://developer.yahoo.com/weather/
), and echoes the feed back.
For example, suppose you make the following request:
http://examples.mashupguide.net/lib/yui/examples/connection/assets/weather.php?p=94720
The script echoes back the following:
http://xml.weather.yahoo.com/forecastrss?p=94720
This will be something of the following form:
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?> <rss version="2.0" xmlns:yweather="http://xml.weather.yahoo.com/ns/rss/1.0" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#"> <channel> <title>Yahoo! Weather - Berkeley, CA</title> <link>http://us.rd.yahoo.com/dailynews/rss/weather/Berkeley__CA/*http://weather.yahoo.com/forecast/94720_f.html</link> <description>Yahoo! Weather for Berkeley, CA</description> <language>en-us</language> <lastBuildDate>Mon, 05 Nov 2007 12:53 pm PST</lastBuildDate> <ttl>60</ttl> <yweather:location city="Berkeley" region="CA" country="US"/> <yweather:units temperature="F" distance="mi" pressure="in" speed="mph"/> <yweather:wind chill="62" direction="300" speed="10"/> <yweather:atmosphere humidity="65" visibility="1287" pressure="30.03" rising="2"/> <yweather:astronomy sunrise="6:39 am" sunset="5:06 pm"/> <image> <title>Yahoo! Weather</title> <width>142</width> <height>18</height> <link>http://weather.yahoo.com/</link> <url>http://l.yimg.com/us.yimg.com/i/us/nws/th/main_142b.gif</url> </image> <item> <title>Conditions for Berkeley, CA at 12:53 pm PST</title> <geo:lat>37.87</geo:lat> <geo:long>-122.3</geo:long> <link>http://us.rd.yahoo.com/dailynews/rss/weather/Berkeley__CA/*http://weather.yahoo.com/forecast/94720_f.html</link> <pubDate>Mon, 05 Nov 2007 12:53 pm PST</pubDate> <yweather:condition text="Fair" code="34" temp="62" date="Mon, 05 Nov 2007 12:53 pm PST"/> <description><![CDATA[ <img src="http://l.yimg.com/us.yimg.com/i/us/we/52/34.gif" /><br /> <b>Current Conditions:</b><br /> Fair, 62 F<BR /><BR /> <b>Forecast:</b><BR /> Mon - Sunny. High: 69 Low: 46<br /> Tue - Partly Cloudy. High: 70 Low: 47<br /> <br /> <a href="http://us.rd.yahoo.com/dailynews/rss/weather/Berkeley__CA/*http://weather.yahoo.com/forecast/94720_f.html"> Full Forecast at Yahoo! Weather</a><BR/> (provided by The Weather Channel)<br/> ]]></description> <yweather:forecast day="Mon" date="05 Nov 2007" low="46" high="69" text="Sunny" code="32"/> <yweather:forecast day="Tue" date="06 Nov 2007" low="47" high="70" text="Partly Cloudy" code="30"/> <guid isPermaLink="false">94720_2007_11_05_12_53_PST</guid> </item> </channel> </rss>