Home > ADC Services, ADC Website, AJAX, JavaScript, Services, WCF > The Same Origin Policy: JSONP vs The document.domain Property

The Same Origin Policy: JSONP vs The document.domain Property

March 18th, 2010

The Same Origin Policy ensures that the client-side code (JavaScript) running on a website originated from that website. This prevents website http://kahtava.com from accessing resources (via client-side code) on website http://malicious-password-sniffers.com or website http://adam.kahtava.com from executing resources from http://kahtava.com - note that the sub-domains differ, one being kahtava.com, the other being adam.kahtava.com

In most cases The Same Origin Policy is desirable. It helps to prevent malicious code that could potentially reveal sensitive information from being run on arbitrary website. However, the same origin policy also makes it difficult to share resources within a common root domain, or run external widgets on your site (like displaying The Project Badge within your site). There are a couple ways to circumvent The Same Origin Policy, but I focus on JSONP and the document.domain property in this post.

Ways to circumvent the Same Origin Policy

  1. JSONP
  2. Modifying the document.domain property
  3. Creating a server side web proxy

JSONP (JSON with padding)

How it works: JSONP dynamically creates a script element in the head of your HTML document which then requests data from outside your domain. JSONP exploits a loophole in the Same Origin Policy that allows JavaScript from an external sites to be run within your site (much like how web analytic tracking works). The JSON response, when returned, is executed within your browser at which time the JavaScript can manipulate your HTML page / DOM.

An Example Using JSONP with jQuery:

JAVASCRIPT:
  1. (function(){
  2.   $.getJSON('http://adam.kahtava.com/services/open-source/projects.json?project-host:username=github:adamdotcom&callback=?', function(data) {
  3.     alert(data);
  4.   });
  5. })();

Note the callback=? at the end of the URI, in jQuery this indicates a JSONP call.

Pros

  • Lets us make external calls to any endpoint that supports JSONP
  • Lets us make external calls from HTTP to HTTPS
  • Supported by all major browsers

Cons

  • A bit more complex upfront, but most server side technologies support JSONP, browsers are natively supporting JSON, and JavaScript libraries like jQuery continue to abstract away most of the complexity.

The document.domain property

How it works: the document.domain property contains the domain of the server from which the page was loaded. For example, the domain for http://adam.kahtava.com/ would be adam.kahtava.com whereas the domain for http://kahtava.com would be kahtava.com. The Same Origin Policy restricts resource access from kahtava.com to adam.kahtava.com unless we set the document.domain property to the root domain (in this case I'd want it set to kahtava.com to share resources with http://adam.kahtava.com).

An Example using the document.domain property:

JAVASCRIPT:
  1. (function(){
  2.   document.domain = 'kahtava.com';
  3.   $.get('http://adam.kahtava.com/contact-me/', function(data) {
  4.     alert(data);
  5.   });
  6. })();

Pros

  • An easy way to access resources within our root domains
  • Supported by all major browsers

Cons

  • Prevents us from making external calls outside a root domain
  • Prevents us from switching between HTTP and HTTPS
  • Kind of a hack - technically, the document.domain property is supposed to be a read only property, but most browsers also provide set access

JSONP vs document.domain isn't a cut and dry comparison. JSONP lets anyone consume and share data, whereas overriding the document.domain lets you share resources within a common root domain. In simple cases where your only concern is sharing data within a single domain (exclusively on HTTP or exclusively on HTTPS), then overriding the domain works well, but in cases where you want to share or consume external data that may be passed over HTTP or HTTPS you'd probably want to stick with JSONP.

The Project Badge makes use of JSONP so it can work on your website. Most of my publicly available web services also make use of JSONP through a WCF JSONPBehavior.

  1. Emily
    October 6th, 2010 at 20:53 | #1

    Great article! Thank you for the tip.

  1. No trackbacks yet.