Ajax|web|web Services | client
This article describes how to use asynchronous JavaScript and XML (asynchronous JavaScript and XML, AJAX) design patterns to implement a Web browser based SOAP Web service client.
AJAX has been widely used in many well-known WEB application services, such as GMail, Google Maps, Flickr, and odeo.com. By using asynchronous XML messaging, AJAX provides Web developers with a way to extend the value and functionality of their Web applications. The Web services JavaScript Library that is described here expands the infrastructure to enhance AJAX design patterns by introducing support for invoking SOAP-based WEB services.
Invoking Web services from the browser
Invoking a SOAP Web service from a Web browser can be cumbersome because most popular Web browsers are slightly different in generating and processing XML. All browsers are implemented consistently and there are few standard APIs or features for XML processing.
One of the mechanisms in which browsers implement consistent support is the XMLHttpRequest API, which is the core of the AJAX design pattern. Another recent article by Philip McCarthy, published by the DeveloperWorks website, describes the API in detail. XMLHttpRequest is a JavaScript object used to execute asynchronous HTTP requests. Philip McCarthy describes a sequence diagram in his article (see Figure 1), which is helpful in understanding how the XMLHttpRequest object supports AJAX design (see Resources for a link to the full text).
Figure 1. Philip McCarthy's AJAX sequence diagram
from this diagram, you can see clearly how the XMLHttpRequest object works. Some JavaScript that runs in a Web browser creates a XMLHttpRequest instance and a function for asynchronous callbacks. The script then uses the XMLHttpRequest object to perform HTTP operations on the server. When a response is received, the callback function is invoked. Within the callback function, the returned data may be processed. If the returned data happens to be XML, the XMLHttpRequest object will automatically resolve the data using the XML processing mechanism built into the browser.
Unfortunately, the main challenge with using AJAX methods is the detailed process of XMLHttpRequest objects parsing XML automatically. For example, suppose the data I am requesting is a SOAP envelope that contains elements from many different XML namespaces, and I want to extract the value of the property attr in Yetanotherelement. (see Listing 1)
Listing 1. A SOAP envelope that contains more than one namespace
xmlns:xsi= "Http://www.w3.org/2001/XMLSchema-instance" >
Xmlns:n= "Http://example"
xmlns:m= "Urn:example" >
N:attr= "ABC"
xmlns:n= "Urn:foo"/>
|
In Mozilla browsers and Firefox browsers, extracting attr property values is very simple, as shown in Listing 2.
Listing 2. Methods for retrieving attr attribute values in Mozilla and Firefox cannot be used in Internet Explorer
var m = El.getelementsbytagnamens (
' Urn:example ',
' yetanotherelement ') [0].
Getattributens (
' Urn:foo ',
' attr ')
Alert (m); Displays ' abc '
|
About security
Because of the many practical security issues involved, by default, XMLHttpRequest objects in most Web browsers are limited to interacting with resources and services that are hosted in the same domain as the Web page that the user is viewing. For example, if I am accessing a page in http://example.com/myapp/, XMLHttpRequest will only allow access to resources located in the example.com domain. This precaution is necessary to prevent malicious application code from potentially inappropriate access to information that it should not be able to access. Because the Web service client described here is based on XMLHttpRequest, this restriction also applies to the Web service that you will invoke.
If you need to be able to access WEB services that are located in another domain, you can use the following two logical solutions:
Digitally sign JavaScript. By digitally signing a JavaScript script, you tell the Web browser that the script will not perform any malicious activity, and that restrictions on the data that XMLHttpRequest can access should also be canceled.
Use a proxy. A simple solution is to pass all requests from XMLHttpRequest by proxy resources located in the same domain as the loaded page. The agent forwards the XMLHttpRequest request to the remote location and returns the result to the browser. From the point of view of the XMLHttpRequest object, this interaction occurs within the existing security configuration.
Unfortunately, the above code cannot be run in Internet Explorer Version 6 because the browser not only does not implement the Getelementsbytagnamens feature, but it actually uses a very bad method--the XML The prefix of the namespace is treated as part of its element and attribute name.
Internet Explorer lacks support for XML namespaces, which makes it difficult to deal with namespace-intensive XML formats, such as SOAP in a browser-independent manner. Even if you want to do something as simple as extracting property values from the results, you must write special code that enables consistent expectations in multiple browsers. Fortunately, this particular code can be encapsulated and reused.
In order to invoke Web services from a Web browser and handle SOAP messages reliably, you need to understand some security issues first (see sidebar, "About security"). In addition, you will need to write a JavaScript script library (Figure 2) to abstract inconsistencies in the underlying browser XML implementation so that you can work directly with WEB service data.
Figure 2. Invoking Web services through JavaScript in a Web browser that uses Web services JavaScript Library
The Web Services JavaScript Library (ws.js) in Figure 2 is a set of JavaScript objects and utilities that provide basic support for a SOAP 1.1-based WEB service. Ws.js defines the following objects:
ws. Call: A WEB service client packaged with XMLHttpRequest
ws. Qname:xml qualified name implementation
ws. Binder: The basis of a custom XML serializer/deserialization
ws. Handler: The basis of the request/response handler
soap. Element: The basic SOAP element that wraps the XML DOM
soap. The Envelope:soap Envelope object extends SOAP. Element
soap. The Header:soap Header object extends SOAP. Element
soap. The Body:soap body object extends SOAP. Element
xml: Cross-platform practical approach for XML processing
The core of Ws.js is WS. The call object, which provides a way to invoke the Web service. Ws. Call is primarily responsible for interacting with the XMLHttpRequest object and handling the SOAP response.