Search code examples
ajaxxmlhttprequestsproutcorecors

Cross origin request with SproutCore in IE9


I am trying to build a web app based on SproutCore 1.8. To retrieve data from a server the app makes CORS requests to a REST web service running on a separate domain.

The code for this looks like the following:

var request = SC.Request.getUrl('http://example.com/some/path');
request.set('attachIdentifyingHeaders', NO);    
request.json().notify(this, this.didFetchData).send();

This works great in Chrome, Safari and Firefox, but it doesn't work in Internet Explorer 9. In fact, IE9 runs into a JavaScript error "Access Denied" in SproutCore's internal request implementation. The error is raised at this line:

// initiate request.
rawRequest.open(this.get('type'), this.get('address'), async);

After some short investigation I found out that Microsoft implemented a dedicated XDomainRequest object for CORS requests in IE9. This does not seem to be supported by SproutCore as I infer from these lines (SproutCore native request implementation selection):

return tryThese(
  function() { return new XMLHttpRequest(); },
  function() { return new ActiveXObject('Msxml2.XMLHTTP'); },
  function() { return new ActiveXObject('Microsoft.XMLHTTP'); }
);

Is this a shortcoming of SproutCore or am I missing something? If so, do you have any suggestions as to how I could work around the issue without writing my own request abstraction?

Note that CORS is a requirement of the existing server infrastructure I am working with. I can neither put the service on the same domain as the server delivering the client nor can I solve the problem with a reverse-proxy or similar infrastructure stuff.


Solution

  • You have two options

    1) Hack Sproutcore itself. You could try adding

    function() {return new XDomainRequest(); }

    to that list of difference xhr conveyances. Add it first; if it's available on the browser it will be used, otherwise the the code falls back to the other objects.

    2) If you don't want to modify the SC source, you can create your own App.CorsResponse class that extends SC.XHRResponse. In your implementation, provide your own createRequest method and do what I said in 1). Whenever you create a request, specify the responseClass to be your custom implementation.