$ http.get no está permitido por Access-Control-Allow-Origin pero $ .ajax es

Tengo un problema para obtener json de un servidor remoto que controlo. Tengo 2 aplicaciones web, una que sirve datos y que se ejecuta en el puerto 3311, y la otra, que solicita datos, se ejecuta en el puerto 5000.

usando jquery los siguientes trabajos:

$.ajax({ url: "http://localhost:3311/get-data", type: 'GET', dataType: 'json', beforeSend: function(xhr) { xhr.setRequestHeader("x-some-header", "some-value"); } }) .done(function(data) { $rootScope.$apply(function() {d.resolve(data); }); }) .fail(function(data) { $rootScope.$apply(function() {d.reject(data); }); }); 

al intentar la misma solicitud get con angular

 $http .get("http://localhost:3311/get-data", { headers: {"x-some-header": "some-value"} }) .success(function(data) { d.resolve(data);}) .error(function(data) { d.reject(data); }); 

Recibo el error

 Origin http://localhost:5000 is not allowed by Access-Control-Allow-Origin. 

El registro de la consola muestra un error que ocurre después de que la solicitud OPCIONES devuelve HTTP200

 OPTIONS http://localhost:3311//get-data 200 (OK) angular.min.js:99 (anonymous function) angular.min.js:99 l angular.min.js:95 m angular.min.js:94 (anonymous function) app.js:78 b.extend.each jquery-1.9.1.min.js:3 b.fn.b.each jquery-1.9.1.min.js:3 (anonymous function) app.js:76 d angular.min.js:28 instantiate angular.min.js:28 (anonymous function) angular.min.js:52 updateView angular-ui-states.js:892 e.$broadcast angular.min.js:90 transition angular-ui-states.js:324 h angular.min.js:77 (anonymous function) angular.min.js:78 e.$eval angular.min.js:88 e.$digest angular.min.js:86 e.$apply angular.min.js:88 e angular.min.js:94 o angular.min.js:98 s.onreadystatechange angular.min.js:99 

y los encabezados que se devuelven desde la solicitud OPTIONS son

 HTTP/1.1 200 OK Cache-Control: private Content-Type: text/plain Server: Microsoft-IIS/8.0 Access-Control-Allow-Origin: * Access-Control-Allow-Methods: GET, POST, OPTIONS Access-Control-Allow-Headers: Content-Type, Accept, X-Requested-With, x-some-header X-AspNet-Version: 4.0.30319 X-SourceFiles: =?UTF-8?B?.... X-Powered-By: ASP.NET Date: Tue, 21 May 2013 01:52:37 GMT Content-Length: 0 

Esto probablemente se deba al comportamiento predeterminado de Angular para incluir el encabezado de solicitud 'X-Requested-With' , que puede causar problemas con CORS. Esto se solucionó en v 1.1.1 (la twig inestable – ver v1.1.1 correcciones de errores ) eliminando el encabezado de solicitudes de dominios cruzados: https://github.com/angular/angular.js/issues/1004 .

Es fácil eliminar el encabezado y hacer que esto funcione en la twig 1.0. La siguiente línea eliminará el encabezado de todas las solicitudes (no solo CORS) realizadas por el servicio $ http en su aplicación:

 yourModule .config(function($httpProvider){ delete $httpProvider.defaults.headers.common['X-Requested-With']; }); 

Actualización Una pequeña advertencia: Angular (como jQuery) no es compatible con CORS para IE9. IE10 es el primer navegador IE que admite CORS. Este blog describe cómo puede obtener soporte CORS en IE8 / IE9 bajo ciertas condiciones, pero no funcionará con el servicio Angular $ http: http://blogs.msdn.com/b/ieinternals/archive/2010/05/ 13 / xdomainrequest-restrictions-limitations-and-workarounds.aspx

web.config

        

La respuesta anterior resolvió el problema.

      

Cuando una página HTML llamaba a un controlador angular con un servicio como:

 $http.get(dataUrl).success(function (data) { $scope.data.products = data; }) .error(function (error) { $scope.data.error = error; }); 

Los encabezados solicitados deben establecerse en el lado del servidor. Hay muchas formas de configurar esto

1. Uno puede ser

   ResponseFilter org.apache.catalina.filters.CorsFilter   ResponseFilter /*  

2. Independientemente del servidor, puede desarrollar una clase personalizada que se pueda pasar como init paramter a jersey servlet com.sun.jersey.spi.container.ContainerResponseFilters helpers.TestCorpsFilter enter code here `public class TestCorpsFilter implementa ContainerResponseFilter {

  @Override public ContainerResponse filter(ContainerRequest arg0, ContainerResponse arg1) { ResponseBuilder resp = Response.fromResponse(arg1.getResponse()); resp.header("Access-Control-Allow-Origin", "*").header("Access-Control-Allow-Methods", "GET, POST, OPTIONS"); String requestHeader = arg0.getHeaderValue("Access-Control-Request-Headers"); if (requestHeader != null && !requestHeader.equals("")) { resp.header("Access-Control-Allow-Headers", requestHeader); } arg1.setResponse(resp.build()); return arg1; }