web-dev-qa-db-fra.com

Angular2 à REST Problème WebApi CORS

J'utilise un frontal angular2 et un backend WebApi. La webapi est compatible CORS

var cors = new EnableCorsAttribute("*", "*", "*");
GlobalConfiguration.Configuration.EnableCors(cors);

et cela fonctionne, car j'ai différents sites (jQuery/Javascript) qui utilisent cette api. Mais avec angular2, ce n'est pas le cas. J'obtiens le message suivant:

La réponse à la demande de contrôle en amont ne passe pas la vérification du contrôle d'accès: aucun en-tête "Access-Control-Allow-Origin" n'est présent sur la ressource demandée.

Peut-être que quelque chose est lié à la "demande de contrôle en amont"?

17
Marcos

J'ai eu le même problème dans mon application Angular2. Le problème, comme déjà indiqué, est qu'avant chaque demande faite par le client, une demande de contrôle en amont est envoyée au serveur.

Ce type de demande a un type OPTIONS , et il est du devoir du serveur de renvoyer un réponse de contrôle en amont avec le statut 200 et les en-têtes défini pour accepter les demandes de ce client.

Voici ma solution (avec express):

// Domain you wish to allow
res.setHeader('Access-Control-Allow-Origin', 'http://localhost:3000');

// Request methods you wish to allow
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE');

// Request headers you wish to allow
res.setHeader('Access-Control-Allow-Headers', 'YOUR-CUSTOM-HEADERS-HERE');

// Set to true if you need the website to include cookies in  requests
res.setHeader('Access-Control-Allow-Credentials', true);

// Check if preflight request
if (req.method === 'OPTIONS') {
    res.status(200);
    res.end();
}
else {
    // Pass to next layer of middleware
    next();
}

Comme vous pouvez le voir, j'ai défini les en-têtes, puis récupéré si le type de demande est OPTIONS . Dans ce cas, je renvoie un état 200 et termine la réponse.

De cette façon, le client sera autorisé et vous pourrez également définir vos en-têtes personnalisés dans toutes les demandes.

9
Matteo Tosi

Votre message d'erreur indique qu'il n'y a pas de Access-Control-Allow-Origin dans la réponse de votre appel. C'est quelque chose de nécessaire pour activer CORS pour cette demande. Ce n'est pas quelque chose lié à Angular2.

Ceci est déclenché côté client par l'ajout de l'en-tête Origin dans la requête. Avez-vous cet en-tête dans votre demande? Utilisez-vous des demandes de contrôle en amont dans vos autres applications. Pour rappel:

  • Demandes simples . Ce cas d'utilisation s'applique si nous utilisons HTTP GET, HEAD et POST. Dans le cas de POST, uniquement les types de contenu avec les valeurs suivantes sont pris en charge: text/plain, application/x-www-form-urlencoded et multipart/form-data.
  • Demandes de contrôle en amont . Lorsque le cas d'utilisation "demandes simples" ne s'applique pas, une première demande (avec la méthode HTTP OPTIONS) est effectuée pour vérifier ce qui peut être fait dans le contexte des demandes interdomaines.

Peut-être que les requêtes OPTIONS ne sont pas correctement traitées côté serveur (ne renvoyez pas les en-têtes corrects, ...).

Ce qui serait intéressant, c'est de nous dire sur quelles requêtes l'erreur se produit: celle des OPTIONS ou la requête cible. Vous pouvez jeter un œil à l'onglet Réseau dans DevTools ...

Voir ces liens pour plus de détails sur le fonctionnement de CORS:

J'espère que cela vous aide, Thierry

8
Thierry Templier

Avez-vous des options définies dans votre fichier web.config pour les cors? c'est-à-dire quelque chose comme <add name="Access-Control-Allow-Origin" value="*"/>

Si oui, assurez-vous de supprimer cela et de contrôler les cors via le code uniquement.

La réponse ici vous aidera.

1
Chidilives

À des fins de développement, ajoutez this Chrome et activez le partage de ressources entre origines).

1
Shamsul

Je sais que la question ne demande pas PHP. Je suis arrivé ici à cause de toute cette chose de contrôle en amont et Angular2. Quand j'ai regardé la réponse de Matteo, j'ai réalisé pourquoi la demande à mon serveur venait revenir avec 401. Cela parce que dans le navigateur de contrôle en amont n'envoie pas le jeton d'autorisation et donc le serveur revient avec 401 et le navigateur pense que CORS n'est pas autorisé. Veuillez noter que le code ci-dessous ne doit être utilisé dans le serveur de développement que si vous savez ce que tu fais.

Dans PHP vous pouvez le faire:

if (strtolower($_SERVER['REQUEST_METHOD']) === 'options') {
         header('Access-Control-Allow-Origin: ' . $_SERVER['HTTP_Origin']);
         header('Access-Control-Allow-Methods: POST, GET, OPTIONS');
         header('Access-Control-Allow-Headers: Origin, X-Requested-With, Content-Range, Content-Disposition, Content-Type, Authorization');
         header('Access-Control-Allow-Credentials: true');
         echo 'Allowed';
         exit;
}

OU Nginx

if ($request_method = 'OPTIONS') {
        add_header 'Access-Control-Allow-Origin' '*';
        add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
        #
        # Custom headers and headers various browsers *should* be OK with but aren't
        #
        add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type';
        #
        # Tell client that this pre-flight info is valid for 20 days
        #
        add_header 'Access-Control-Max-Age' 1728000;
        add_header 'Content-Type' 'text/plain charset=UTF-8';
        add_header 'Content-Length' 0;
        return 204;
     }

N'oubliez pas quels que soient les autres en-têtes que vous envoyez au serveur, vous devez être ajouté à la liste Access-Control-Allow-Headers.

1
Jsonras

J'ai également eu du mal avec les cors et angular 6.

lorsqu'une demande adressée au serveur n'est pas une demande de base, une demande de contrôle en amont demande à votre serveur s'il peut répondre à votre demande.

le serveur qui répond à cette demande doit avoir les en-têtes suivants:

Access-Control-Allow-Origin // devrait être votre domaine

Access-Control-Allow-Headers // doit être Accept, Origin, tout autre en-tête que vous pourriez avoir.

Access-Control-Allow-Method // toutes les méthodes que vous utilisez

ce sont les "*", "*", "*" que vous avez ajoutés en tant qu'attributs Cors pour tout accepter, mais cela ne fonctionnait pour moi en mode développeur que lorsque le client et le serveur étaient sur la même machine. après que je suis passé en production avec le serveur IIS ces valeurs ne fonctionnaient plus, surtout à cause des en-têtes.

donc c'est vraiment facile à réparer et ça marche aussi pour IOS à la place * * * j'ai ajouté ceci à chaque contrôleur:

[EnableCors(origins: "enter your domain here", headers: "authorization, Origin, Accept, X-Requested-With, Content-Type, Access-Control-Request-Method, Access-Control-Request-Headers", methods: "GET,POST", PreflightMaxAge = 600 // optional, SupportsCredentials = true // optional)]

vous pouvez en savoir plus dans l'article qui m'a aidé à comprendre ce que je devais faire: https://msdn.Microsoft.com/en-us/magazine/dn532203.aspx

J'espère que ça aide, Tomer.

0
Tomer Halaf

Vous pouvez ajouter un module complémentaire dans votre navigateur Firefox. Cela fonctionnera dans votre navigateur Firefox comme un charme. Cors Everywhere a résolu mon problème. https://addons.mozilla.org/en-US/firefox/addon/cors-everywhere/

0
SUBHASIS MONDAL

Je travaille avec Angular 2 pour le front-end et nodeJS (Expressjs) pour l'API

Angular 2 travaille sous localhost: 3000 et express travaille sur localhost: 8000

Le problème se produit lorsque localhost: 3000 essaie d'appeler une URL avec la méthode POST ... Le serveur expressJS rejette l'appel car il provient d'un autre serveur (ou port)

Pour résoudre le problème, vous devez dire au nœud js d'accepter les appels du serveur localhost: 3000 ...

Vous pouvez trouver une bibliothèque (CORS) pour éviter ce problème dans ce lien :

0