Cross-Domain Magics

Intro

As the browser applications get more and more complex in years, some of them are designed to deploy on multiple domains for reusing, maintaining, as well as some special requirements. Also some Internet campanies provide their data (search, medias, user auth.,etc) to the public as web services on their domains. In order to meeting these new requirements, your applications must have the ability to get cross-domain resources. However, cross-domain request is forbidden in XMLHttpRequest object as a security policy, so we need some other ways instead of XHR. Here are some of current popular solutions on the Internet

a) window.name transport

I would like to introduce window.name transport firstly because in Formvine we do it in this way. Here are words from “window.name Transport” on SitePen (my remark in bracket)

window.name transport

window.name transport

name is a property of the global/window object in the browser environment, and the value of the name property remains the same as new pages are navigated for the frame. By loading a resource in an iframe where the target page will set the name property for its frame, this name property value can be retrieved (by host domain) to access the information sent by the web service (on another domain).

The basic process of window.name transport is like following:

  • (main page) insert a hidden iframe to the DOM with a target page from another domain as “src”.
  • (main page) attempt to get iframe.name with code in a “try-catch” block repeatedly (when source page is still on the other domain, an exception will be thrown as you get the window name).
  • (target page) in the response of the target page, set the data to window.name with javascript.
  • (target page) redirect the iframe to a page in the host domain with javascript.
  • (main page) get the iframe.name successfully.

Security concern

window.name transport is considered as a secure solution for cross-domain requests as no code from the unsafe domain will be executed. It’s just a string in the window.name. You can decide when and how to get data you want from the string, or just do eval() on it after necessary validation. It’s passive, or “pull”.

However, there is still an issue with this solution caused by the long-live feature of the value of window.name: the target page can also get the name of the iframe when you perform the next cross-domain request with the same iframe. So remember to destroy the iframe as every request, or at least clear the value of iframe.name.

See
“window.name Transport” on SitePen
for more contents about window.name transport, including description of the implementation in Dojo.

b). JSONP: JSON with padding

JSONP has been well known as a widely used cross-domain solution for several years, which is also used by Jesse in the GI cross-domain build.

As we know, script node is designed as an exception of the “same origin policy” which means we can set the source of a script node to a page on any domain. So basicly you can request a page http://domainB.com/get.php?param1=value&cb=func which response some javascript code as the contents of the script node. And this code will be executed in the scope of your window once the response is ready. In the response javascript, a named callback function (“cb=func” in your request) will be invoked with the data your want from the other domain.

Security concern

The issue is: you never get chance to check the response code to decide if it should be executed or not. Also the code is executed in your window scope which means it has the full ability to get anything in your window. So you must trust the “unsafe domain” as it won’t response any harmful code doing anything on sensitive data in the application.

For more info on JSONP, see JSONP in wikipedia.org.

b+). JSONP with sandbox

JSONP in Sandbox

JSONP in Sandbox

There are so many API providers using JSONP which makes JSONP very popular although it has security concern. Most of time we developer have to “trust” the service provider such as Google, Yahoo. However, now we have a better manner to get out of the security concern. It’s actually a combine of window.name transport and JSONP: using JSONP in a “sandbox” page to communicate with “unsafe” APIs, then using window.name transport to get data safely from the sandbox. At worst the code responsed from “unsafe” domain can only do harm in the sandbox page, which certainly contains no sensitive data (even no data other than the request related). Also the main page get a chance to validate the data from APIs as it retrieves data from window.name of the iframe.
See “Sandbox Your Cross Domain JSONP To Improve Mashup Security” on Beebole.com for more details.

c). Server proxy

Another traditional solution for cross-domain is server proxy. Here is a picture from Yahoo which describe the cross-domain process:

Server Proxy

Server Proxy

The basic idea is: there’s no cross-domain restriction on the server side, so we can make a server application which is deployed in the same domain to handle all cross-domain request from client side, just like the picture is showing.

There’s also a big problem about the server proxy solution that no http session is created between the client and the “unsafe” server, which means some business requirements based on session (cookie) are unavailable on this way, such as third-party user authentication. Sometime you can use a session token instead of the browser session to perform authentication. But it’s not all.

However, for the services which are not related to particular session, server proxy is enough. And it’s safe.
See “JavaScript: Use a Web Proxy for Cross-Domain XMLHttpRequest Calls” on Yahoo! Developer Network for how to use web proxy for Yahoo APIs.

c+). Use YQL as public web proxy

It’s easy to make a web proxy on your own domain. But it’s sometime also an interesting idea to not maintain any server code in your application – all “reusing”, all “service”, all in the “cloud”, blabla, 😀 You may take help from web proxy which is provided as public service from Internet service provider such as Yahoo!.

Here are descriptions of YQL from Yahoo Developer Center:

The Yahoo! Query Language is an expressive SQL-like language that lets you query, filter, and join data across Web services. With YQL, apps run faster with fewer lines of code and a smaller network footprint.

For more details on YQL see http://developer.yahoo.com/yql/

But for now what we need to know is “YQL can help you query contents at a URI”. We can use a YQL expression like “select * from xml where url=’http://domainC.com/sample.xml'” to get the whole xml content. As we use it from client side with JSONP, Yahoo provides a service url which accepts the expression and other options as request parameters, like http://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20xml%20where%20url%3D’http%3A%2F%2Frss.news.yahoo.com%2Frss%2Ftopstories’&format=json&callback=cbfunc. Use this url as your JSONP target, cbfunc will be called with the target xml in JSON format after response.

I don’t think YQL is suitable for the enterprise application. But it’s acceptable if you don’t want to maintain the web proxy in your personal application.

More …

For GI developer only:
Although it has quite little probablity GI applications are required to deployed on multiple domains, I was wondering how it works on that way. As there is an avaiable attribute “path” of the record in plugins.xml by which you can define where the engine fetch the plugin from, I did a few changes on AMP engine code to handle the requests to plugins having a  “path” attribute beginning with “http://” with jsx3.net.Request.XD, instead of jsx3.net.Request as original. I use YQL as the web proxy to fetch resources on other domains. And I create a AMP project on domain A with only one plugin deployed on domain B. It works well (of course … =.=). I may write another one to talk about it. For a demo you can try http://lab.nuttycoder.com/amplus/launcher.html and check the net requests with firebug.

This entry was written by Wang Xiaoxing , posted on Sunday January 31 2010at 04:01 am , filed under Javascript, 富客户端 | RIA and tagged , , , , , , . Bookmark the permalink . Post a comment below or leave a trackback: Trackback URL.

26 Responses to “Cross-Domain Magics”

Leave a Reply

XHTML: You can use these tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>