Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

IE9,IE8 with AngularJS CORS returns “Access is denied” - ASP.NET WebApi

In IE8 and 9 I am getting the following JavaScript Error when I'm doing a CORS webapi call:

Error: Access is denied.
{
  [functions]: ,
  description: "Access is denied.",
  message: "Access is denied.",
  name: "Error",
  number: -2147024891
}

I set up my WebApi like described here http://www.asp.net/web-api/overview/security/enabling-cross-origin-requests-in-web-api

So the WebApi contains:

  public static class WebApiConfig
  {
      public static void Register(HttpConfiguration config)
      {
          config.EnableCors(new EnableCorsAttribute("*", "*", "*"));
      [...]

My test AngularJS App:

  <!DOCTYPE html>
  <html xmlns="http://www.w3.org/1999/xhtml" xmlns:ng="http://angularjs.org" ng-app="app">
  <head>
      <title>test</title>
      <script src="Scripts/angular.js"></script>
      <script src="app.js"></script>
  </head>
  <body>
      <div ng-controller="testController as vm">
          {{vm.test}}
          {{vm.data}}
      </div>
  </body>
  </html>

app.js:

  var app = angular.module('app');

  app.controller('testController', function ($http) {
      var vm;
      vm = this;

      vm.test = "bla non no ";
      vm.data = null;

      $http.defaults.headers.common['Authorization'] = 'a token'

      return $http({
          method: 'GET',
          data: null,
          url: 'http://webapi.com/api/controller/getactionmethod/',
      }, function (data) {
          console.log("bla");
      }).success(function (data, status, headers, config) {
          console.log("bla a");
          vm.data;
      });


  });

The above code / webapi calls works with chrome and IE 10. IE10 prints:

SEC7118: XMLHttpRequest for http://webapi.com/api/controller/getactionmethod/ required Cross Origin Resource Sharing (CORS). SEC7119: XMLHttpRequest for http://webapi.com/api/controller/getactionmethod/ required CORS preflight.

I'm really stuck and don't know what I can try else. Any ideas?

like image 365
Briefkasten Avatar asked Oct 10 '14 16:10

Briefkasten


2 Answers

I had the same issue with IE8/9 (Django backend instead of ASP.NET) when doing CORS requests.

There are several ways to solve this problem. The easiest and fastest solution for me was to use the polyfill from jpillora. With this polyfill normal CORS XMLHttpRequests will be swapped out for XDR on IE8/9.

Include XHook and add following before-hook to your site:

xhook.before(function(request, callback) {
  //skip browsers that dont use XDR
  if(!window.XDomainRequest)
    return callback();
  //skip requests that aren't cross domain
  var url = request.url;
  var loc = window.location;
  var hostname = loc.hostname + (loc.port ? ":"+loc.port : "");
  if(!/^https?:\/\/([^\?\/]+)/.test(url) || RegExp.$1 === hostname)
    return callback();

  //if not GET, force POST
  var method = request.method;
  if(method !== 'GET') method = 'POST';
  //force same protocol
  url = url.replace(/^https?:/,loc.protocol);
  //request!
  var xdr = new window.XDomainRequest();
  xdr.timeout = request.timeout;
  //proxy events
  var proxy = function(e) {
    xdr['on'+e] = function() {
      request.xhr.dispatchEvent(e);
    };
  };
  var events = ['progress','timeout','error'];
  for(var i = 0; i < events.length; ++i )
    proxy(events[i]);
  //custom onload
  xdr.onload = function() {
    callback({
      status: 200,
      statusText: "OK",
      headers: {
        'Content-Type': xdr.contentType
      },
      text: xdr.responseText
    })
  };
  xdr.open(method, url);
  xdr.send(request.body);
  return
});

There are several other solutions:

  • https://github.com/Modernizr/Modernizr/wiki/HTML5-Cross-Browser-Polyfills#cross-origin-resource-sharing-cors
  • https://github.com/jpillora/xdomain
  • https://michiganlabs.com/easy-cors-legacy-browsers/#.VglHEye1FBd
like image 164
bjunix Avatar answered Nov 04 '22 23:11

bjunix


AngularJS v1.2.23 does not support CORS requests for IE8 or IE9. But IE8/9 supports CORS limited with the XDomainRequest object. See also http://msdn.microsoft.com/en-us/library/ie/cc288060(v=vs.85).aspx

I tried to modify the angularjs lib like descriped here http://samuellam.wordpress.com/2013/08/03/ie-89-cors-support-in-angular-js/

But I noticed I can't send with the XDomainRequest requests a custom header. So I ended up deploying the project on the same machine with same ips which will work for IE8 and 9, which is in fact only a workaround.

http://blogs.msdn.com/b/ieinternals/archive/2010/05/13/xdomainrequest-restrictions-limitations-and-workarounds.aspx

like image 37
Briefkasten Avatar answered Nov 04 '22 22:11

Briefkasten