Sunday, April 13, 2008

Advanced Web Programming Techniques: Dynamic Script Tags

I was researching some techniques for doing Comet programming, and I ran across a PowerPoint presentation on Dynamic Script Tags.  If you speak GWT, you'll find they outline this technique in their FAQ.  Here's the basic idea.

First, a little background about the Javascript Same-Origin Policy, first introduced in Netscape 2.  From The Art of Software Security Assessment blog, "same-origin prevents a document or script loaded from one site of origin from manipulating properties of or communicating with a document loaded from another site of origin. In this case the term origin refers to the domain name, port, and protocol of the site hosting the document."  These restrictions extended to XmlHttpRequests (xhr), i.e. a script cannot make an xhr to a domain other than the one from whence the script originated.

The Same-Origin Policy poses a bit of a problem for two kinds of AJAX applications.  First, the developer attempting to make xhr calls to sub-domains (see my previous post on web performance optimization) will have problems.  Generally (IE & FF only?), Resources are not of the same origin if they have a different URL, essentially.  Scripts, however, from the same top-level domain can set the document.domain property to the TLD to allow them to interact.  This doesn't solve the xhr problem.  The second type of AJAX application that can be fettered by the Same-Origin Policy is the mashup.  Most mashups proxy the browser request to get the data from the others sites.  In other word, xyzmaps.com would have all of its scripts/xhr point to xyzmaps.com which would in turn make an HTTP request to e.g. maps.google.com, essentially proxying the browser request.  This presents a huge difficulty for implementing mashups, as all requests have to be proxied through the origin server.  A more thorough understanding of the Same-Origin Policy leads us to a better solution.

If you've ever used the Google maps API or the Virtual Earth api, you'll note that you include the api in your page via script tags.  Of course, this works perfectly for many sites, but doesn't it violate the Same-Origin Policy?  It does not, in fact, because the browser rightly assumes that scripts included via tags in the document are "safe" insofar as they are not alien.  So, we can get around the Same-Origin Policy by  adding script tags from other domains in our document.  This works statically in or pages, but we can also add script tags dynamically via script DOM manipulation!  Thus, a better solution than proxying requests for our mashups is found.

So, SiteA dynamically adds a script tag whose src attribute is set to a url on SiteB that will generate JavaScript, embedding the name of SiteA's callback method in the request.

There are several other rather unsatisfactory approaches outlined at Abe Fettig's Weblog.