Sign In/My Account | View Cart  
advertisement


Listen Print Discuss

It's still no fun to work around the cross-domain security restriction that web browsers impose on the XMLHttpRequest object (and IE's XMLHTTP ActiveX object), but with the advent of more interesting REST web services, Ajax developers are looking for ways to make web services requests directly from client web browsers, rather than loading down their servers.

The cross-domain request restrictions guideline, or Same Origin Policy, which has governed browser security since almost the beginning of recorded browser history (Netscape Navigator 2.0), has spawned a number of clumsy workarounds--many of which have probably been used by folks interested in simplifying their Ajax mashups and applications.

The usual workaround is to use server-based proxies, which I discuss here. For the more daring, there's the limited yet powerful Dynamic Script Tag approach. However, the latest entry in the field of hacks and workarounds has some potential advantages over all of these (See Table 1). Based on Adobe (nee Macromedia) Flash technology and written by Julien Couvreur, the FlashXMLHttpRequest proxy, currently in stable beta, is a small (less than 5K) Flash SWF file that can make HTTP GETs and POSTs on your Ajax application's behalf.

Table 1
Table 1. XMLHttpRequest compared to the Dynamic Script Tag (Click image for full-size screen shot).

Related Reading

Ajax Hacks
Tips & Tools for Creating Responsive Web Sites
By Bruce W. Perry

FlashXMLHttpRequest has two primary advantages over other approaches. First, it's truly cross-platform since it works the same in any web browser with Flash versions 6, 7, or 8 installed (close to 95% of modern desktop web browsers). Second, it has a simple security model to allow cross-domain requests, which is already in use by many sites that offer web services, such as Yahoo and Amazon. The security is implemented on the server side by placing a single text file, named crossdomain.xml, in the root directory of the domain that hosts the web services. Rules in the file specify which domains or IP addresses are allowed to make web services requests. On the client side, cross-domain access is denied by default, but if the client finds a crossdomain.xml file on the server and the rules allow it to connect, a request can proceed. You can view examples of crossdomain.xml files for Amazon and Yahoo here and here, respectively.

From a security standpoint, another advantage is that any cookies that are returned to the browser as a result of the HTTP request aren't accessible from the SWF file or the supporting JavaScript, so security issues involving access to the client's cookies aren't available to malicious JavaScript scripts.

Using FlashXMLHttpRequest

FlashXMLHttpRequest consists of several SWF files, one for Flash 8 and two that support both Flash 6 and 7. JavaScript detects the version of Flash in the client browser and the appropriate SWF file is loaded. The Dojo JavaScript Toolkit provides the interface layer between your Ajax application and the Flash SWF files, and almost all of the JavaScript code overhead (at least 115K, the size of the dojo.js file) comes from the Dojo JavaScript libraries. (Work is under way to reduce the JavaScript code overhead, so future versions may be smaller.) To support JavaScript-to-Flash communication in Flash 6 and 7, Brad Neuberg created the DojoExternalInterface library to emulate the JavaScript-to-Flash communication interface in Flash 8 (called ExternalInterface).

Using FlashXMLHttpRequest is quite easy, as Couvreur has written a JavaScript wrapper that makes it work superficially like the XMLHttpRequest object. Figure 1 shows a simple example that executes an HTTP GET request of a Yahoo web service. (It searches for podcasts that have the word "fun" in the title or description and returns only the first result found.) The file FlashXMLHttpRequest.js, referenced at the top of the example, detects the version of Flash in the client browser and loads the appropriate SWF file.

<html>
<head>
<!-- Bring in the Dojo interface libraries and the FlashXMLHttpRequest wrapper -->  
<script type="text/javascript" src="../dojo-0.3.0-ajax/dojo.js"></script>
<script type="text/javascript" src="FlashXMLHttpRequest.js"></script>

<script type="text/javascript">
var xhr = null;
// Initialize the Flash interface and specify an "onload" function as the argument 
InitFlash("doMyCall");// This is the callback function for the FlashXMLHttpRequest below 
function showPodcast() {
       // Just display the raw XML response in an alert box 
       alert(xhr.responseText);
}
function doMyCall() {
       // Create the request object 
       xhr = new FlashXMLHttpRequest();
       // This is our Web Services call 
       var p = 'http://api.search.yahoo.com/AudioSearchService/V1/podcastSearch?appid=YahooDemo&query=fun&results=1';
       // Specify the callback function 
       xhr.onload = showPodcast;
       // Set the Content-Type header
       xhr.setRequestHeader("Content-Type", "text/xml");
       // Make the request 
       xhr.open('GET', p);
       xhr.send("");
  }
</script>
</head>
<body>
</body>
</html>

Code example: An HTTP GET using FlashXMLHttpRequest

FlashXMLHttpRequest suffers from a few limitations, some more annoying than others. It cannot receive HTTP status codes or send/receive HTTP headers, nor can it do HTTP PUT or DELETE, which limits its use by more sophisticated REST web services implementations. To be fair, these limitations are imposed by Flash 6 and 7; Flash 8.0 can receive HTTP status codes and send/receive HTTP headers, and Flash 8.5 will be able to handle HTTP PUTs and DELETEs.

Note that although the developer cannot explicitly send and receive HTTP headers, the HTTP Content-Type header can be set, which turns out to be quite useful if a type of data other than XML is requested, e.g., JSON or Serialized PHP. The request result is returned as a plain-text string, responseText. It is up to the developer to parse it into an object. The ability to send arbitrary HTTP headers will likely be a future enhancement to FlashXMLHttpRequest.

You can try out Julien Couvreur's demo, which demonstrates both HTTP GET and POST, here. Download the binary runtime here or the full source here.

Under Development

There are good security reasons why XMLHttpRequest is constrained by the Same Origin Policy mentioned earlier. But there are ways to design a pure JavaScript cross-domain request solution that will allow requests without compromising user security, and at least two proposals are on the table to add an additional function to future browsers that would allow cross-domain requests. Douglas Crockford's JSONRequest and Chris Holland's ContextAgnosticXMLHttpRequest are both proposals that allow HTTP requests from one domain to another while carefully considering the security ramifications.


Comment on this articleShare your experience in our forums.
(* You must be a
member of XML.com to use this feature.)
Comment on this Article


Titles Only Titles Only Newest First
  • 24 HOur Locksmith Lockout Service Assistance Los Angeles 1-323-678-2704
    2009-07-02 15:01:17 carpetcare [Reply]

    24 Hour Emergency Towing Service
    24 Hour Winching Service
    24 Hour Battery and Jumpstart Assistance
    24 Hour Flat Tire Service
    24 Hour Lost Key and Lockout Service
    Up to $100 for a Locksmith
    24 Hour Out-of-Gas Fuel Delivery
    Emergency Transportation Service
    24 Hour Emergency Personal Assistance
    24 Hour Map and Routing Service
    Roadside Assistance Small Maintenance Repair Fixing Auto Services.
    24 Hour Emergency Towing Service: As a member, your vehicle can be towed up to 15 miles to the repair facility of your choice. We will pay up to $100.00 for winching services if necessary. Note: Only one tow per disablement.


    24 Hour Winching Service: If your vehicle is stuck and you only need to have your vehicle extracted by use of a winch, then we cover that too.


    24 Hour Battery and Jumpstart Assistance: If you are unable to get your car started, a maintenance person will be sent to provide a battery jump and help you get your car running again. Whether on the road or parked at home we will send someone out. If your battery cannot be jumped then your vehicle will be towed to a repair facility of your choice.


    24 Hour Flat Tire Service: We will send a maintenance person to you to change your vehicle's flat tire to a drivable spare, enabling you to drive to safety. It is your responsibility to have a safe and working spare with your vehicle at all times.


    24 Hour Lost Key and Lockout Service: We will send a pre-authorized contractor to unlock your vehicle using manufacturer approved tools. If there is not a network contractor available in your area, as a member, you are entitled to $100.00 toward the cost of a locksmith.
    Licensed, Insured & Bonded Professional Locksmiths



    24 Hour Out-of-Gas Fuel Delivery: If you should run out of gasoline, a service technician will deliver fuel to get you on your way. Your membership includes 3 gallons of fuel delivered to you free of charge.


    Emergency Transportation Service: If you find yourself on the side of the road with your car disabled give us a call and we will arrange transportation for you for up to 15 miles. This service can only be used instead of another service. It is for those times where you just have to get where you are going whether your vehicle is disabled or not.


    24 Hour Emergency Personal Assistance: During any weather related or roadside emergency, our customer service staff can relay messages to loved ones and receive messages for you, helping you to put your mind at ease.
    http://www.roadsideassistancelosangeles.com
    1-877-364-5264

  • Example Error
    2007-01-11 13:46:29 ameikle [Reply]

    Hi -- I uploaded your example to my test server and i'm getting an error.
    "FlashXMLHTTPRequest is not defined"
    I'm then pointed to the dojo.js file.


    Any clues on what I may be missing?

    • Another implementation
      2009-05-03 04:04:05 boris_reitman [Reply]

      I ended up rolling my own version and shared with the world:


      http://code.google.com/p/crossxhr/

    • Example Error
      2007-01-16 16:09:13 ameikle [Reply]

      I was able to get it to work by downloading the example links and start modifying the example page. Everything worked from there on.


      Real slick stuff Julien.