web-dev-qa-db-fra.com

Problèmes AngularJS CORS

J'ai cherché sur plus de 200 sites (peut-être exagéré, mais pas beaucoup) sur la façon de gérer les cors avec angularjs. Nous avons une machine locale exécutant un serveur d'API Web. Nous développons un client qui fait appel à l'API pour les données. Lors de l'exécution du client à partir du serveur, nous recevons des données sans problème. Lorsque nous l'exécutons à partir d'un domaine différent, nous obtenons une réponse rouge 200 lorsque nous essayons de récupérer des données et une réponse vide. Voici du code:

var myApp = angular.module('Project', ['ngResource']);

myApp.config(function($routeProvider){
    $routeProvider.
        when('/new', {templateUrl:'templates/new.html', controller:'EditProjectController'}).
        when('/mobile', {templateUrl:'templates/mobile.html', controller:'ProjectController'}).
        when('/it', {templateUrl:'templates/it.html', controller:'ProjectController'}).
        when('/writing', {templateUrl:'templates/writing.html', controller:'ProjectController'}).
        when('/all', { templateUrl: 'templates/all.html' }).
        when('/login', { templateUrl: 'partials/_login.html' }).
        otherwise({ redirectTo: '/all' });
});
myApp.config(['$httpProvider', function ($httpProvider) {
$httpProvider.defaults.useXDomain = true;
delete $httpProvider.defaults.headers.common['X-Requested-With'];
}
]);



myApp.controller('ProjectController', 
function myApp($scope, $http, projectDataService, userLoginService) {
    $http.defaults.useXDomain = true;
    $scope.loadProject = function(){
        projectDataService.getProject(function(project){
            $scope.project = project;
            })


    };
    $scope.loadProject();
}

);

myApp.factory('projectDataService', function ($resource, $q) {
var resource = $resource('http://webapiserver/api/:id', { id: '@id' });
return {
    getProject: function () {
        var deferred = $q.defer();
        resource.query({ id: 'project' },
            function (project) {
                deferred.resolve(project);
            },
            function (response) {
                deferred.reject(response);
            });

        return deferred.promise;
    },
    save: function (project) {
        var deferred = $q.defer();
        project.id = 'project/9';
        resource.save(project,
            function (response) { deferred.resolve(response); },
            function (response) { deferred.reject(response); }
            );
        return deferred.promise;
    }
};
});

J'ai également essayé ceci en utilisant $ http mais j'obtiens la même réponse (ou son absence):

myApp.factory("projectDataService", function ($http) {

return {
    getProject: function (successcb) {
        $http.get("http://webapiserver/api/project").
        success(function (data, status, headers, config) {
            successcb(data);
        }).
        error(function (data, status, headers, config) {

    }
};
});

Lorsque je viens de parcourir l'URL qui sert le json dans le navigateur, il crache les données. Sur le serveur, nous autorisons les origines interdomaines, ce qui ressort de ma déclaration précédente. Comme vous pouvez le voir, j'implémente les remplacements d'en-têtes dans myApp.config, j'ai même essayé de le mettre directement dans mon contrôleur ... aucune différence ...

3 jours maintenant sur cette tâche.

L'aide à cet égard est PLUS qu'appréciée. Merci d'avance.

42
Shane

Vous devrez peut-être modifier un peu votre API Web. J'ai rencontré le même type de problème et j'ai écrit un article sur la façon de résoudre ce problème.

J'ai utilisé Sinatra pour l'API, je ne sais pas quelle langue vous utilisez pour vos services Web mais je suppose que vous pouvez l'appliquer. Fondamentalement, vous devez configurer votre serveur pour accepter les appels CORS en définissant quelles origines et quelles méthodes HTTP sont autorisées.

Vous avez dit que vous l'aviez déjà activé sur votre serveur, mais qu'avez-vous fait exactement?

Voir cet article pour plus de détails: CORS avec angular.js

11
T_Dnzt

Si vous voulez POST sur votre WebApi avec des données, vous devrez en faire un peu plus pour que Chrome fonctionne. Vous aurez besoin de pour intercepter le contrôle en amont et inclure l'origine des clients comme origine autorisée.

S'il existe une meilleure solution pour cela, après plusieurs jours de travail sur ce problème exclusivement, je ne l'ai pas trouvé. Enfin, c'est ce qui a fonctionné pour moi.

Bonne chance...

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Http;
using System.Web.Routing;

namespace MashupCoreApiApi
{
    public class WebApiApplication : System.Web.HttpApplication
    {
        protected void Application_Start()
        {
            GlobalConfiguration.Configure(WebApiConfig.Register);
        }


        protected void Application_BeginRequest(object sender, EventArgs e)
        {

            if (Context.Request.Path.Contains("api/") && Context.Request.HttpMethod == "OPTIONS")
            {

                Context.Response.AddHeader("Access-Control-Allow-Origin", Context.Request.Headers["Origin"]);
                Context.Response.AddHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
                Context.Response.AddHeader("Access-Control-Allow-Methods", "GET, POST PUT, DELETE, OPTIONS");
                Context.Response.AddHeader("Access-Control-Allow-Credentials", "true");
                Context.Response.End();
            }

        } 

    }
}
2
user3448990

Vous devez modifier un peu votre API Web pour gérer les demandes interdomaines. Incluez la bibliothèque Microsoft Asp-Net Server Cors dans le projet Web Api et quelques autres modifications de niveau de code et vous êtes prêt à partir. Pour en savoir plus ici.

Votre Angular est très bien.

0
Nitin Rawat

Si c'est ASP.NET WebAPI, vous devez installer le package CORS et initialiser CORS au démarrage du serveur Web.

Le package est appelé Microsoft.OWin.Cors

Dans le WebiApiConfig.cs mettre quelque chose comme:

var cors = new EnabledCorsAttribute("*", "*", "DataServiceVersion, MaxDataServiceVersion");
config.EnableCors(cors);
0
pinnprophead