The internet is one of the largest nets in the entire world. Here are some things that I like/find humorous/want others to see/what-have-you.

CORS: Worth Geeking Out Over

Feb
05
Posted on February 5, 2012 at 5:36 pm

As was recently and nerdily mentioned on Connection Café, I’ve been working with the world-class engineering team at Convio to implement support for Cross-Origin Resource Sharing (CORS) in the new release of our API. Despite having been around since Firefox 3.5 (and, like, Chrome 2.0), CORS has received little attention from the web development community at large. In my opinion, it is the most revolutionary and exciting change to the Internet in a long while, and deserves much more fanfare than things like, say, box-shadow.

So what is this “CORS” thing anyway?

At a super high level, CORS changes one of the fundamental (and annoying) rules of the web, the same origin policy, allowing domaina.com to share information with domainb.com. The same origin policy was put in place to prevent would-be hackers from reading personal information about you from the websites you frequent. Were it not for the same origin policy, I could easily embed some code on the page you’re viewing right now to steal your deets from, say, Amazon.com. While it’s obviously a really good thing that I can’t do that, this long-standing rule-with-no-exceptions is unbelievably frustrating for those of us who build web applications. It’s 2012; a lot has changed since the same origin policy was introduced in Netscape 2.0. There are plenty of completely legit reasons to need to share information across multiple domains. Thankfully, CORS now allows for doing exactly that. To use my previous example, if Amazon.com wants me to be able to read some (not-so-personal) information from its website, all it has to do is simply return a response header, Access-Control-Allow-Origin, indicating that my domain is allowed in.

Try it out!

To give a real life, working example, this simple little bit of HTML and JavaScript will retrieve and display a random image of my son, Kjonaas, when placed on any domain.

<!DOCTYPE html>
<html>
<head></head>
<body>
<div id="kjonaas"></div>
<script type="text/javascript">
var xhr=new XMLHttpRequest();
var requestURI='http://iamnoahcooper.com/kjonaas-elton-cooper/random.php';
var ts=new Date().getTime();
var showPhoto=function(xml){
	var photo=xml.getElementsByTagName('photo')[0];
	document.getElementById('kjonaas').innerHTML='<img src="'+
	photo.getElementsByTagName('large')[0].firstChild.nodeValue+
	'" alt="" /><br />'+
	photo.getElementsByTagName('caption')[0].firstChild.nodeValue;
};
if('withCredentials' in xhr){
	xhr.open('get',
	requestURI+'?ts='+ts,
	true);
	xhr.onload=function(){
		showPhoto(this.responseXML.getElementsByTagName('kjonaas')[0]);
	};
	xhr.send();
}
else if(typeof XDomainRequest!='undefined'){
	xhr=new XDomainRequest();
	xhr.open('get',
	requestURI+'?ts='+ts);
	xhr.onload=function(){
		var xml=new ActiveXObject('Microsoft.XMLDOM');
		xml.async=false;
		xml.loadXML(this.responseText);
		showPhoto(xml.getElementsByTagName('kjonaas')[0]);
	};
	xhr.send();
}
</script>
</body>
</html>

If you examine the HTTP request to that little Kjonaas API I created, you’ll see the following header included in the response:

Access-Control-Allow-Origin: *

This is CORS in its most basic form — because I don’t need to worry about who can access the information this API returns, I’ve indicated that any domain that wants to is allowed to retrieve the XML. If I did want to restrict access to the API to, say, my wife’s website, I’d just need to return a more explicit header:

Access-Control-Allow-Origin: http://www.sarahpcooper.com

If it’s not clear to you yet, I’m in love with CORS.

I mean seriously enthralled. For years, like so many other web developers who pay their rent by writing AJAX, I’ve been hacking together solutions to do this exact thing, with various and sundry libraries, hidden iframes, and in moments of true desperation, Flash. The beauty of CORS is that, as seen above, it requires only a few lines of native JavaScript. What’s more, CORS is supported by almost every modern browser — Internet Explorer 8+, Firefox 3.5+, Safari 4+, and Chrome have all embraced it, and it works just as well on a phone or tablet as it does on a desktop. The one notable exception is Opera, though they’ve recently announced that support for CORS will be included in Opera 12.

But it’s not all rainbows and unicorns, not yet at least.

If you actually read my JavaScript above, you’ll note that I have an obnoxious but necessary if statement. As is so often the case, Microsoft decided to go with its own implementation of CORS rather than the standard adopted by its peers. To take advantage of CORS in IE, web developers must use the proprietary XDomainRequest object. Fortunately, IE10 preview indicates that Microsoft may have seen the error of its ways, and will support the standard XMLHttpRequest going forward.

The biggest catch, though, is IE’s Same Scheme policy, which isn’t terribly well documented, so you might not know it exists until you run into it like I did. Same Scheme says that even with the advent of CORS, domaina.com can only share information with domainb.com if both use the same protocol. If you place my code above on a page served over HTTPS, and attempt to view that page in IE8 or IE9, you’ll get a JavaScript error. As a web developer for a company whose APIs are generally only accessibly over HTTPS for security reasons, this makes me want to rip every last one of my hairs out of my skull. Hopefully in adding support for XMLHttpRequest, Microsoft will also ditch Same Scheme. It’s hard to tell if that is the case or not, given that IE10 preview is only available for Windows 8.

Microsoft issues aside, start using CORS!

If you’re a developer, I strongly encourage you to evangelize for CORS at your company every opportunity you get. It’s surprisingly simple to implement, especially given how long its taken the Internet to come around to the idea that cross-domain resource sharing is ubiquitous, and not just for people with .ro email addresses hawking cheap Viagra.

Leave a Reply

7 Responses to CORS: Worth Geeking Out Over

  1.  

    |

    • hello!I’m using ijetty and I’m rnuinng it in one android emulator, in the same machine I’m rnuinng another emulator and I would like to reach the apps rnuinng in the ijetty in the first one I can do it from the desktop by using adb forward tcp:8888 tcp:8080, but I can not do it from the other emulator How can I do to reach it?I have another question I would like to create a webapp and put it in ijetty, what tools may I use for that? Now I’m trying with eclipse and the m2eclipse plugin, but I don’t know how it exactly works, anyway, I’ll keep trying to figure this out. Thanks for your help!!greetingsalberto

  2. like yr blog, remember yr posts at the fubfalo listserv (where i do some lurking). so anyway, good stuff. appreciate yr saying that poems are processes, that every little bit of it, the writing, revisions, palimpsests are the poems too. never finished, always undone, and therefore always a beginning. looked for yr email her but didn’t see it. please do keep up the blogging. on everything, poems, chess, and yr daily living as a human poet. take care,richard

  3. Pingback: Server-Sent Events: They’s Niiice | Noah Cooper's Blog