|
25 Mar 2009 09:32 am
|
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:
- 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.
- 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.
- 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.
- 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)

One thing that really bothers me is that MSFT had to build a separate API.
I’ve been using the JSONP support in jQuery to handle xdomain requests in our widget library. They embed on 3rd party pages in Google Maps fashion and we’ve had very few problems with this approach.
Injecting script tags that point to RESTful web service seems shaky…but it’s a good work around for now while this other stuff matures. (good enough for google maps and gadgets also)
@mattcarbone
Matt – Completely agree with the MS API. This would have been a good opportunity to support the XMLHttpRequest object.
jQuery does have good JSONP support but it would be useful to have full HTTP Request support (headers, body, all methods, etc…) to any server. Unfortunately the spec by the W3C seems really backwards and insufficient.
Bob (Buffone)
[...] Rockstarapps.com » Unleash the Browser with Cross-Domain Requests … [...]