Seeing the feature list for the latest version of IE (8), I was excited to download it and get started exploring one feature in particular – that was the new XDomainRequest object. The XDomainRequest object gives developers the ability to access resources outside of the original application’s host domain (www.rockstarpps.com for my blog).  This limitation was imposed to eliminate sending sensitive data to bad people for nefarious reasons.  Even with this restriction, developers have been able hack around the browser limitation get Cross Domain (aka cross-site) functionality.

Cross-Domain (aka Cross-Origin, Cross-site) requests aren’t new to the Web world they have been available in Flash for some time.  As a supporter of the Open Web, I try to do most of my application development in HTML, CSS and JavaScript. Every now and then I get the urge to build a new application to prototype a thought or fill a singular niche (That’s one that I will most likely find interesting or useful).

That’s how the Snipper application came about. When I was done with the basic functionality, I decided to build a web application that did essentially what the eclipse plugin does.

  • Submit Content to S3
  • Update Status on Twitter
  • Submit Content to S3

Services without Servers

Another thing I have been reading about lately are articles on Tim Berners-Lee’s concept of linked-data. The concept is interesting and the way I have envisioned this working is what I call “Services without Servers”. As a developer, I should be able to create new Services without having any servers either shared, hosted, or in the cloud that run code I have written. Using only APIs and the user’s machine, I should be able to create a service. This is how I envisioned the Snipper web application working. Assembling different content into a browser-based application; I would use JavaScript create the running application.

The page that displays the snippet is done in just this manner using JavaScript, web-based data and the following services; Twitter, js-kit, tinyurl, Amazon S3 the page is assembled on the client.

 

This works great for displaying data but for producing data the current browser environment is insufficient.

You might have done this:

Knowing I needed to integrate twitter, I went to the twitter.com/api page and started looking for the JavaScript API. “Let’s see…”

  • ActionScript/Flash, C++, C#/.NET, Java, Objective-C/Cocoa, Perl, PHP, PL/SQL, Python, Ruby, Scala

Damn it, where’s the JavaScript? Oh yeah, that’s right it can’t be done because there isn’t Cross domain functionality. ActionScript & Flash have libraries because the flash engine can access resources outside of the host domain.

Flash & Flex

Flash & Flex applications allow developers to access cross domain sites using a configuration file that is retrieved from the applications host domain. This file configures the flash engine to allow access to certain domains. An example of the cross domain configuration file is embedded below.

<?xml version="1.0"?>
<!-- http://snipper.rockstarapps.com/crossdomain.xml -->
<cross-domain-policy>
    <allow-access-from domain="www.twitter.com"/
    <allow-access-from domain="*.twitter.com"/>
    <allow-access-from domain="105.216.0.40"/>
</cross-domain-policy>

This approach makes sense because it allows the host domain to secure which domains can be called. If the application tries to call a 3rd party domain that is not allowed, the request can be stopped.  This approach also allows integration of 3rd party libraries without worry of them sending data to anyplace other than the ones specified.  Lastly, this approach works with any third party service.  Twitter does not need to do anything special to allow Flash & Flex clients to access their services as they don’t for PHP, Java or any other technology… Not so fast, lets see what the W3C has come up with.

W3C & Open Web

Currently the W3C is working on a Cross-Origin Specification. I am not going to go Zed Shaw, but I have to admit that I don’t get the approach of the W3C. Having a working model already on the Web (Flash) the W3C came up with a whole different model of cross domain requests.

Instead of the having the host domain provide the browser with the list of sites the browser is allow to talk to. It is up to the 3rd Party to determine if they allow requests from a certain origin. What? Let me explain.

In this model the browser has access to all websites. When a cross domain request is made the browser will add the “Origin” header to the request.  Below is the contents of the a XDomainRequest in IE8.

Cross Domain Request:

GET /test.php HTTP/1.1
Host: www.rockstarapps.com
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.1b3) Gecko/20090305 Firefox/3.1b3
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-us,en;q=0.5
Accept-Encoding: gzip,deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Keep-Alive: 300
Connection: keep-alive
Referer: http://www.rockstarapps.com/samples/crossdomain/index.html
Origin: http://www.rockstarapps.com

It is up to the end point of the request to respond that they except cross domain requests. In order to do this they respond at a minimum with the “Access-Control-Allow-Origin” header. Below is a snippet of PHP code to respond with the header.

3rd Party:

<?php
    header("Access-Control-Allow-Origin: *");
?>

I see several big issues with the what the W3C has provided as a basis for cross domain:

  1. Puts the onus on the 3rd party providers.  This means that all 3rd party services need to add the access control header.  I can’t just use the new IE 8 browser to start interacting with 3rd party services like twitter. Every response to a request by twitter, flickr or any other needs to supply this header at a minimum. Why? They don’t need to do this for any other client of their service.
  2. Can’t protect 3rd party libraries from sending to unknown destinations. If I load a JavaScript library it can send data to anyone it wants.
  3. The Client sends data even before the service is verified. It is speced that Browser is supposed to issue what is called a Pre-flight Request to verify the supported methods and headers but I ran both IE 8 and the firefox beta through a proxy and didn’t see this work.
  4. I need to change my server code to support this type of interaction. Also the service provide is responsible for keeping a list of the domains. There are what – a billion plus internet domains registered.  Now everyone needs to keep track.

Overall I think the approach is completely backwards from the way it is supposed to work. Flash & Flex will still be needed if you want to build a client only application on the web.

The one application model that this spec makes sense is where the user chooses the endpoint. Take an application like Bespin, they could offer a portable repository model that makes it possible for any third party to supply settings and project information as long as they support some JSON specification.  How would it work?  Load the application from the Bespin site and then choose a code repository. In this workflow the W3C model would provide a vehicle for creating this application.

Native Support

IE 8:

New in IE 8 is the XDomainRequest which provides the ability to execute requests outside of the application hosts domain.  To see how to use it check out this code snippet. One of the down falls of the object is that is has a very limited API, click to see API. Doesn’t seem to be the same functionality as the normal requests; headers, set body content, multipart posts.  Again this limits the usefulness of the API for building applications.

Everyone Else (Tested in Firefox 3.1.3 beta):

The rest of the browsers will use the XMLHttpRequest which will presumably have the same functionality as it does for non cross-domain requests. Click here to see how to use the native API.

NOTE: Don’t try to run this through the from http://localhost/<app> and call  http://127.0.0.1/request.php. I didn’t get this to work and needed to change my host file as they did in this video.  Kinda sucks but easy enought to work around when you know.

NOTE:  The Cross domain requests would fail if you try to run the browser through a proxy. This happened, I did see it fail in IE and firefox but couldn’t reproduce it, I guess it was my fault.

Library Support

As of testing the latest release libraries using the Google Ajax Libraries API which makes this kind of testing extremely easy. Now, I don’t think that any library should support the Cross Domain requests at this point. None of the libraries tested support the new XDomainRequest.

  • Prototype – Errors in both IE8 and Firefox 3.1.beta
  • Mootools – Errors in both IE8 and Firefox 3.1.beta
  • Dojo – Errors in both IE8 and Firefox 3.1.beta
  • jQuery  – Errors in both IE8 and Firefox 3.1.beta

Test Application

I have created a test application that allows you to try out the Cross Domain functionality. I have tested it in IE8 and the Firefox 3.1.3 beta. Only the HTML is required to run the application. The test file that is requested looks as follows:

<?php
    header("Access-Control-Allow-Origin: *");
?>
 { 
   "name": "Bob Buffone",
   "blog": "http://www.rockstarapps.com/wordpress",
   "myData": <?php echo $_GET["mydata"]; ?>
 }

Screen shot of test application. Click to see for yourself.

Conclusion

My feelings after researching the Cross Domain functionality is that it really isn’t ready to build applications.  Unfortunately, theW3C didn’t get what the people would try to do with cross domain requests. Therefore, it will be along time before I go to the twitter api page and see a JavaScript library. What I am looking for in the browser is the same support to execute requests as PHP, Java.  Limiting the API doesn’t protect the data in the page, it just limits the usefulness of the browser to deliver more functional applications.

Bob (Buffone)