Cross-domain Request object and CORS

There are several scenarios where we would need to perform a request against a different subdomain. Originally that was not possible by default(although there are some workarounds) due to the same domain restrictions. Cross-Origin Resource Sharing (CORS) extends the original same domain restrictions in several ways.

One of them is the definition of a new header rule (Access-Control-Allow-Origin) that allows to perform cross domain (and subdomain) requests if they match the origin host of the request.

Those new rules seem to be fully supported in modern versions of Firefox >=12, Chrome >=18 and Internet Explorer >= 10.

Imagine that in the previous example we are in http://www.example.com, trying to do a GET/POST request to http://api.example.com, and that server has been configured to return a correct Access-Control-Allow-Origin header.

The request will be sent successfully in Chrome, Firefox and Internet Explorer 10.

Unfortunately, Internet Explorer versions 8 and 9 (also IE7 running in compatibility mode from IE8/9) won't accept those requests, throwing an "Access is denied" exception (in the first code snippet, line 14).

There are several workarounds to fix crossdomain scenarios. Such as iframe combined with document.domain, or libraries like easyXDM.

The latter is probably the better solution if you want to be really sure that your crossdomain issue is going to be fixed in all the different browsers. Although if you control the list of targeted browsers: (like modern versions of Chrome, Firefox, Safari and IE>=8) and you don't want to affect the performance requiring an external library or iframes ("they are 1-2 orders of magnitude more expensive to create than any other type of DOM element"), then you can use CORS, but in the case of Internet Explorer <10 you'll need to use the XDomainRequest object if you want to perform the cross domain AJAX request.

Internet Explorer 8 supports the XDomainRequest object, an implementation based in the XMLHttpRequest object but with several security restrictions.

Some of the constraints of XDomainRequest:

  1. Requests must be targeted to the same schema: e.g. not allowed from HTTPS to HTTP.
  2. The request can't have custom headers.
  3. Only requests with text/plain as content-type
  4. Cookies, HTTP credentials, client certificates, etc, are not sent

We can combine XMLHttpRequest and XDomainRequest solutions, performing a fallback in case that the XMLHttpRequest request fails. But take in mind that both objects doesn't share the same interface. Hence you can not just return an XDomainRequest object expecting to be used exactly the same as you'd use a XMLHttpRequest object.

Finally, coming back to the initial example, if the first request using XHR fails, we can detect if the XDR object is present, and then we'd be able to perform the request to the different subdomain:

Reference:

Cross-Origin Resource Sharing draft

CORS for XHR in IE10

XDomainRequest object reference