This document comments on the code samples in “ Asynchronous JavaScript and XML Highlights.” The samples serve to summarize all of the AJAX implementations supported by Songhay System, providing explicit constraints for Web client design specifications.
The infamous problem with Web clients is the standards problem. These proprietary Web browsers implement XML over HTTP differently. It follows that our approach to AJaX is necessarily simple. Our primary approach to AJaX design is the attempt to deliver responseText to innerHTML. See responseText in action in “Using the XML HTTP Request object.” The following attempts to summarize why this approach is taken:
responseXML exposes a “reference type” of unknown quality. Ideally we get an object like that described in “ECMAScript Language Binding.” But this is only hope.responseText produces a “value type”—a string. Those who are impressed by the concept of “inner XML” should understand quickly the advantage here. The nodeValue property in a responseXML object is another reference type of unknown quality. Will nodeValue return “mixed content”—the text node scalar and child elements as a string? Or will it just return the text node scalar?responseText implies that there will be little or no client-side manipulation of data. The opinion here, as of this writing, is that Web browsers are still poor platforms for complex XML-based applications. We can look forward to companies like Google™ to make this opinion clearly ridiculous.responseText should eventually demand tightly-coupled, well-formed REST data from the server. This should not be a problem for Songhay System but it is understandable why other designs depend on relatively large client-side JavaScript frameworks (like dojo) when the REST server is not under developer control.The first example in “ Asynchronous JavaScript and XML Highlights” defines the pattern that will be used throughout the samples. The essential div elements are TabularDataMessage and TabularDataTableBlock:
<h2>Get Tabular Data</h2>
<div id="TabularDataBlock">
<div><button onclick="jsTabularData()">Get Data</button></div>
<div id="TabularDataMessage"></div>
<div id="TabularDataTableBlock"></div>
</div>
The asynchronous callbacks are sent to TabularDataMessage started by the JavaScript function jsTabularData(), defined in the inline script block below:
<script type="text/javascript">
var ajTabularData = new Ajax()
var requestTabularData = null
function jsTabularData()
{
var vUri = './restCaller.php?cmd=table1'
requestTabularData = ajTabularData.Send(vUri,true,'jsTabularDataReqHandler')
}
function jsTabularDataReqHandler()
{
var div = window.document.getElementById('TabularDataMessage')
if(!ajTabularData.IsXmlLoaded(requestTabularData))
{
div.style.display = 'block'
div.innerHTML = ajTabularData.Message
return
}
else
{
div.style.display = 'none'
with(window.document.getElementById('TabularDataTableBlock'))
{
innerHTML = requestTabularData.responseText
}
}
}
</script>
The first line in the script block refers to the custom Songhay System class, Ajax(). This relatively small effort was made in spite of the existence of dojo, primarily because the scope of dojo.io is quite sweeping, while, as of this writing, Songhay System confines itself to supporting Microsoft Internet Explorer 5.x and Firefox 1.x (which should cover Opera and Safari). This effectively means that Ajax() asynchronous input/output is based on the XmlHttpRequest object. This rather small “surface area” of browser compatibility means that our AJAX functionality should be used where failure does not disable the entire Web page.
The first line in jsTabularData() defines the URI of the server-side “rails” script, restCaller.php, transporting data from within and across domains to the client. This script describes a REST ‘server’ because it returns XML. Our tabular data example renders an XHTMLtable element from an Ajax() call based on a static XML file, tabular.xml. The rails script transforms tabular.xml with the XSLT file, ajax.xslt. The opinion here is that it is easier to declare the AJaX table in the XSLT file instead of rendering it client-side in a lengthy JavaScript procedure.
Our “ Asynchronous JavaScript and XML Highlights” presentation depends on a PHP5 script, restCaller.php, featuring these lines of code:
if(strlen($restUri) > 0)
$c = curl_init($restUri);
curl_setopt($c, CURLOPT_RETURNTRANSFER, 1);
$s = curl_exec($c);
curl_close($c);
$xml = simplexml_load_string($s);
$xsl = new XSLTProcessor();
$xsl->importStyleSheet(DOMDocument::load('./ajax.xslt'));
$xsl->setParameter(null,'cmd',$cmd);
$xhtml .= $xsl->transformToXML($xml);
//Note that Firefox 1.x will attempt to render the XHTML as HTML without this line:
$xhtml = str_replace(' xmlns="http://www.w3.org/1999/xhtml"','',$xhtml);}
echo $xhtml;
The value for $restUri is determined by the “query string” of the request (setting the value of $cmd) and we see that ajax.xslt is the server side star of the show. This AJaX design permits server-side domination. The server is used almost exclusively to render client-side data and user interface elements. Since a server-side “proxy” script is required by the current AJaX security model to access data across domains, this design seems appropriate.
Note that $c is set by cURL. Many Web hosts require the use of cURL for security reasons. As an example, see how my current host introduces cURL with respect to PHP.
The “Get Amazon.com REST Data” sample in “ Asynchronous JavaScript and XML Highlights” uses server-side XSL transformations. This quote under “Using XSLT with ECS” from the Amazon E-Commerce Service (ECS) SDK is very important to this sample:
You must create a namespace prefix at the top of your style sheet. In previous versions of ECS, it was possible to use the default namespace, which meant that you did not need to specify a namespace to access elements in the response. This is no longer the case.
My misunderstanding of this change had me losing several hours trying to figure out why libxslt, running under PHP 5 was not working properly. It turns out that I needed to select one of the ECS nodes to get the latest namespace URI. As of this writing, this is http://webservices.amazon.com/AWSECommerceService/2005-10-05.
This last and only POST example is based on “AJAX Form POST Request—HTML Form POST/Submit with AJAX/Javascript Example/Tutorial.” This design has the same structure as the previous ones except for the addition of a data collection function, jsGetFormData() used for the form AjaxForm. The action attribute of AjaxForm is javascript:; and the semi-colon is important because the location javascript: will open JavaScript Console in Firefox.
| Asynchronous JavaScript and XML Highlights (*.zip) | The compressed archive of the files discussed in this article. |
| “Forms in HTML Documents” | Formally defines the bread and butter of REST remote procedure calls—namely “form content types” especially the all-important application/x-www-form-urlencoded type. |
| “Call SOAP Web services with AJAX, Part 1” | IBM of course would plug SOAP—because this means Java. |
| “Async Requests over an Unreliable Network” | “The biggest void in the AJaX discussion, IMO, is how network and server availability affects XMLHttpRequests.” And of course we must prepare for when the network is down. |
| “XMLHttpRequest Call” | The “Handling POSTs and Other Request Types” section makes sense here… |
| AJAX Form POST Request—HTML Form POST/Submit with AJAX/Javascript Example/Tutorial | A straight-forward example of POST in AJaX. |
| AJAX/RPC: “Prevent IE Caching During Partial Page Updates” | Explains why Microsoft Internet Explorer needs a ‘randomized’ URI for multiple calls to the same resource. This is very important when you want to reload AJaX content when the page reloads. |