L'en-tête "Access-Control-Allow-Origin" contient plusieurs valeurs

104

J'utilise AngularJS $ http côté client pour accéder à un point de terminaison d'une application API Web ASP.NET côté serveur. Comme le client est hébergé sur un domaine différent de celui du serveur, j'ai besoin de CORS. Cela fonctionne pour $ http.post (url, données). Mais dès que j'authentifie l'utilisateur et fais une demande via $ http.get (url), je reçois le message

L'en-tête «Access-Control-Allow-Origin» contient plusieurs valeurs «http://127.0.0.1:9000, http://127.0.0.1:9000», mais une seule est autorisée. L'accès d'origine 'http://127.0.0.1:9000' n'est donc pas autorisé.

Fiddler me montre qu'il y a en effet deux entrées d'en-tête dans la requête get après une requête d'options réussie. Quoi et où est-ce que je fais quelque chose de mal?

Mettre à jour

Lorsque j'utilise jQuery $ .get au lieu de $ http.get, le même message d'erreur apparaît. Cela ne semble donc pas un problème avec AngularJS. Mais où est-ce mal?

Papa Mufflon
la source
Eh bien, que contient l'en-tête?
eckes le

Réponses:

53

J'ai ajouté

config.EnableCors(new EnableCorsAttribute(Properties.Settings.Default.Cors, "", ""))

aussi bien que

app.UseCors(CorsOptions.AllowAll);

sur le serveur. Cela entraîne deux entrées d'en-tête. Utilisez simplement ce dernier et cela fonctionne.

Papa Mufflon
la source
4
Il semble que vous lisiez Properties.Settings.Default.Cors à partir d'un fichier de paramètres. Pouvez-vous poster un exemple? Et dans quelle classe appartient UseCors?
Hoppe
"Uncaught ReferenceError: EnableCorsAttribute n'est pas défini" ??
circuitry
@ Hoppe, veuillez consulter msdn.microsoft.com/en-us/library/dn314597(v=vs.118).aspx . Il explique que le premier paramètre de EnableCorsAttribute est les origines autorisées. Par exemple "*" pour tout autoriser.
Papa Mufflon
1
@Hoppe, UseCors est une méthode d'extension définie dans le package NuGet Microsoft.Owin.Cors. Sf katanaproject.codeplex.com/SourceControl/latest#src/… .
Papa Mufflon
7
config.EnableCors (enableCorsAttribute) est généralement appelé dans WebApiConfig.cs - il fait partie du package Microsoft.AspNet.WebApi.Cors Nuget, dont l'utilisation est décrite ici: asp.net/web-api/overview/security/… app .UseCors (CorsOptions.AllowAll) est généralement appelé dans Startup.Auth.cs dans le cadre de la configuration de votre fournisseur d'identité (par exemple OAuth) et fait partie du package Microsoft.Owin.Cors Nuget.
Henry C
51

Nous avons rencontré ce problème car nous avions configuré CORS selon les meilleures pratiques (par exemple http://www.asp.net/web-api/overview/security/enabling-cross-origin-requests-in-web-api ) ET AUSSI avait un en-tête personnalisé <add name="Access-Control-Allow-Origin" value="*"/>dans web.config.

Supprimez l'entrée web.config, et tout va bien.

Contrairement à la réponse de @ mww, nous avons toujours EnableCors()dans le WebApiConfig.cs ET un EnableCorsAttributesur le contrôleur. Lorsque nous avons éliminé l'un ou l'autre, nous avons rencontré d'autres problèmes.

Brandon Kuczenski
la source
11
J'ai supprimé cette ligne <add name = "Access-Control-Allow-Origin" value = "*" /> et j'avais les deux autres entrées suivantes dans le fichier web.config que je n'ai pas supprimées: <add name = "Access -Control-Allow-Headers "value =" Content-Type "/> <add name =" Access-Control-Allow-Methods "value =" GET, POST, PUT, DELETE, OPTIONS "/>
Siva Karthikeyan
2
C'est la clé, vous ne devez activer CORS qu'une seule fois, mon problème était que je l'avais également activé dans mon web.config ainsi que dans app.UseCors () ... J'ai supprimé l'entrée web.config et j'ai simplement utilisé l'application. (Microsoft.Owin.Cors.CorsOptions.AllowAll); méthode à la place.
Mohammad Sepahvand
1
La ligne ci-dessus m'a sauvé la vie! Assurez-vous de ne pas activer CORS plus d'une fois, sinon cela se produira et vous serez très frustré.
TGarrett le
supprimé le <add name = "Access-Control-Allow-Headers" value = "Content-Type" /> de web.config et corrigé pour moi
jbooker
1
"C'est la clé, vous ne devez activer CORS qu'une seule fois" <- CECI EST CELA @MohammadSepahvand MERCI. Retour à .NET et déjà surpris: D.
Tuan Jinn
42

J'utilise Cors 5.1.0.0, après beaucoup de maux de tête, j'ai découvert que le problème était la duplication des en-têtes Access-Control-Allow-Origin & Access-Control-Allow-Header du serveur

Supprimé config.EnableCors()du fichier WebApiConfig.cs et définissez simplement l' [EnableCors("*","*","*")]attribut sur la classe Controller

Consultez cet article pour plus de détails.

mww
la source
cela fonctionne pour moi, assurez-vous simplement que vous n'en définissez pas un autre comme celui-ci <add name = "Access-Control-Allow-Origin" value = "*" /> dans web.config
Crismogram
12

Ajouter au registre WebApiConfig

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

Ou web.config

<httpProtocol>
<customHeaders>
<add name="Access-Control-Allow-Origin" value="*" />
<add name="Access-Control-Allow-Headers" value="Content-Type" />
<add name="Access-Control-Allow-Methods" value="GET, POST, PUT, DELETE, OPTIONS" />
<add name="Access-Control-Allow-Credentials" value="true" />
</customHeaders>  
</httpProtocol>

MAIS PAS LES DEUX

tfa
la source
2
C'était la solution clé pour moi, ne faites pas les deux.
robnick
8

En fait, vous ne pouvez pas définir plusieurs en-têtes Access-Control-Allow-Origin(ou du moins cela ne fonctionnera pas dans tous les navigateurs). Au lieu de cela, vous pouvez définir conditionnellement une variable d'environnement, puis l'utiliser dans la Headerdirective:

SetEnvIf Origin "^(https?://localhost|https://[a-z]+\.my\.base\.domain)$" ORIGIN_SUB_DOMAIN=$1
Header set Access-Control-Allow-Origin: "%{ORIGIN_SUB_DOMAIN}e" env=ORIGIN_SUB_DOMAIN

Donc, dans cet exemple, l'en-tête de réponse sera ajouté uniquement si un en-tête de demande Origincorrespond à RegExp:^(https?://localhost|https://[a-z]+\.my\.base\.domain)$ (cela signifie essentiellement localhost sur HTTP ou HTTPS et * .my.base.domain sur HTTPS).

N'oubliez pas d'activer setenvif module.

Documents:

BTW. Le }edans %{ORIGIN_SUB_DOMAIN}en'est pas une faute de frappe. C'est la façon dont vous utilisez la variable d'environnement dans la Headerdirective.

Nux
la source
1
Avez-vous une source pour ne pas définir plusieurs en-têtes de contrôle d'accès? Je ne trouve rien qui confirme cela.
Spencer
Solution très intelligente et propre. A travaillé pour moi.
Alex Kalmikov
@Spencer "Remarque: En pratique, la production de la liste d'origine ou de la valeur nulle est plus contrainte. Plutôt que d'autoriser une liste d'origines séparées par des espaces, il s'agit soit d'une seule origine, soit de la chaîne" null " ." w3.org/TR/cors/#access-control-allow-origin-response-header
Nux
8

J'avais aussi OWIN ainsi que mon WebAPI qui avaient apparemment besoin d'activer CORS séparément, ce qui à son tour a créé l' 'Access-Control-Allow-Origin' header contains multiple valueserreur.

J'ai fini par supprimer TOUT le code qui system.webServeractivait CORS, puis j'ai ajouté ce qui suit au nœud de mon Web.Config:

<httpProtocol>
  <customHeaders>
    <add name="Access-Control-Allow-Origin" value="https://stethio.azurewebsites.net" />
    <add name="Access-Control-Allow-Methods" value="GET, POST, OPTIONS, PUT, DELETE" />
    <add name="Access-Control-Allow-Headers" value="Origin, X-Requested-With, Content-Type, Accept, Authorization" />
  </customHeaders>
</httpProtocol>

Cela répondait aux exigences CORS pour OWIN (permettant la connexion) et pour WebAPI (permettant les appels d'API), mais cela créait un nouveau problème: une OPTIONSméthode n'a pas pu être trouvée pendant le contrôle en amont pour mes appels d'API. Le correctif pour cela était simple - j'avais juste besoin de supprimer ce qui suit du handlersnœud my Web.Config:

<remove name="OPTIONSVerbHandler" />

J'espère que cela aide quelqu'un.

Matt Cashatt
la source
7

Serveur Apache:

Je dépense la même chose, mais c'était parce que je n'avais pas de guillemets (") l'astérisque dans mon fichier qui donnait accès au serveur, par exemple '.htaccess.':

Header add Access-Control-Allow-Origin: * 
Header add Access-Control-Allow-Origin "*" 

Vous pouvez également avoir un fichier «.htaccess» dans un dossier avec un autre «.htaccess», par exemple

/ 
- .htaccess 
- public_html / .htaccess (problem here)

Dans votre cas, au lieu de '*', l'astérisque serait le http://127.0.0.1:9000serveur ip ( ) auquel vous donnez l'autorisation de servir des données.

ASP.NET:

Vérifiez qu'il n'y a pas de duplicata 'Access-Control-Allow-Origin' dans votre code.

Outils de développement:

Avec Chrome, vous pouvez vérifier les en-têtes de vos demandes. Appuyez sur la touche F12 et allez dans l'onglet 'Réseau', lancez maintenant la requête AJAX et apparaîtra sur la liste, cliquez et donnez toutes les informations qui s'y trouvent.

Contrôle d'accès-Autoriser-Origine: *

Chofoteddy
la source
Parfois, c'est aussi simple que ça ... En essayant de faire fonctionner ces services Web confondus sur IIS / Chrome, j'ai joué avec la méthode Application_BeginRequest, et je l'ai oublié ... duplication dans mon propre code! Merci de m'avoir indiqué l'évidence! :)
Juergen Riemer
2
Pour obtenir les en-têtes de réponse CORS, vous devrez également simuler une demande d'origine croisée, de sorte qu'elle peut ne pas apparaître si vous regardez simplement dans l'onglet réseau sur le site en cours d'exécution. Cependant, utiliser quelque chose comme DHC ( chrome.google.com/webstore/detail/dhc-resthttp-api-client/… ) pour exécuter votre requête AJAX sera techniquement appelé à partir d'un domaine différent, déclenchant ainsi CORS et vous permettant de voir les en-têtes de contrôle d'accès.
Henry C
4

Cela se produit lorsque l'option Cors est configurée à plusieurs endroits. Dans mon cas, je l'avais au niveau du contrôleur ainsi que dans Startup.Auth.cs / ConfigureAuth.

Ma compréhension est que si vous voulez que l'application soit large, configurez-la simplement sous Startup.Auth.cs / ConfigureAuth comme ceci ... Vous aurez besoin d'une référence à Microsoft.Owin.Cors

public void ConfigureAuth(IAppBuilder app)
        {
          app.UseCors(CorsOptions.AllowAll);

Si vous préférez le garder au niveau du contrôleur, vous pouvez simplement l'insérer au niveau du contrôleur.

[EnableCors("http://localhost:24589", "*", "*")]
    public class ProductsController : ApiController
    {
        ProductRepository _prodRepo;
Nizar
la source
Dans mon cas, je l'avais défini à la fois dans Web.Config et dans MyAppApiConfig.cs. Le retirer de ce dernier a résolu le problème pour moi.
Jim B
4

si vous êtes dans IIS, vous devez activer CORS dans web.config, vous n'avez pas besoin de l'activer dans la méthode App_Start / WebApiConfig.cs Register

Ma solution était de commenter les lignes ici:

// Enable CORS
//EnableCorsAttribute cors = new EnableCorsAttribute("*", "*", "*");
//config.EnableCors(cors);

et écrivez dans le web.config:

<system.webServer>
  <httpProtocol>
  <customHeaders>
    <add name="Access-Control-Allow-Origin" value="*" />
  </customHeaders>
</httpProtocol>

développeur libre
la source
2

Cela peut également se produire bien sûr si vous avez défini votre Access-Control-Allow-Origin tête pour avoir plusieurs valeurs - Par exemple, une liste de valeurs séparées par des virgules, qui est en quelque sorte prise en charge dans la RFC mais n'est pas réellement prise en charge par la plupart des principaux navigateurs. Notez que la RFC explique comment autoriser plus d'un domaine sans utiliser également «*».

Par exemple, vous pouvez obtenir cette erreur dans Chrome en utilisant un en-tête comme celui-ci:

Access-Control-Allow-Origin: http://test.mysite.com, http://test2.mysite.com

C'était dans Chrome Version 64.0.3282.186 (Official Build) (64-bit)

Notez que si vous envisagez cela à cause d'un CDN et que vous utilisez Akamai, vous voudrez peut-être noter que qu'Akamai ne se mettra pas en cache sur le serveur si vous l'utilisez Vary:Origin , comme beaucoup suggèrent de résoudre ce problème.

Vous devrez probablement changer la façon dont votre clé de cache est construite, en utilisant un comportement de réponse «Modification d'ID de cache». Plus de détails sur ce problème dans cette question liée à StackOverflow

Brad Parks
la source
Donc, fondamentalement, vous ne pouvez pas pour le moment, car il est peu probable que vous souhaitiez que chaque domaine sur Internet accède à l'URL.
scottheckel
Le lien Akamai nécessite d'être connecté.
Jean-François Savard
oui, cela semble être une exigence akamai pour ces documents ;-(
Brad Parks
Une autre façon d'obtenir cette erreur dans Chrome est une liste séparée par des espaces de valeurs: Access-Control-Allow-Origin: http://test.mysite.com http://test2.mysite.com. Ce serait la bonne façon, mais les navigateurs ne suivent pas la norme ici ( source ).
tanius
2

Si stupide et simple:

Ce problème s'est produit pour moi lorsque j'ai deux fois Header always set Access-Control-Allow-Origin *dans mon fichier de configuration Apache. Une fois avec les VirtualHostbalises et une fois dans une Limitbalise:

<VirtualHost localhost:80>
  ...
  Header set Access-Control-Allow-Origin: *
  ...
  <Limit OPTIONS>
    ...
    Header set Access-Control-Allow-Origin: *
    ...
  </Limit>
</VirtualHost>

La suppression d'une entrée a résolu le problème.

Je suppose que dans le message original, cela aurait été deux fois:

Header set Access-Control-Allow-Origin: "http://127.0.0.1:9000"
Se flétrir
la source
1

vient d'avoir ce problème avec un serveur nodejs.

voici comment je l'ai réparé.
Je lance mon serveur de nœud via un nginx proxyet j'ai défini nginx et nodeles deux allow cross domain requestset cela n'a pas plu, alors je l'ai retiré de nginx et je l'ai laissé dans le nœud et tout allait bien.

James Harrington
la source
Merci pour cette réponse! Cela a résolu un problème que je ne pouvais pas résoudre depuis longtemps avec une configuration nginx + Rack (Ruby). Même problème, même solution: désactivez les ajouts d'en-tête dans nginx et laissez le rack-corsgem gérer les choses CORS. Bam, fixe.
Pistos
0

J'ai rencontré le même problème et voici ce que j'ai fait pour le résoudre:

Dans le service WebApi, dans Global.asax, j'ai écrit le code suivant:

Sub Application_BeginRequest()
        Dim currentRequest = HttpContext.Current.Request
        Dim currentResponse = HttpContext.Current.Response

        Dim currentOriginValue As String = String.Empty
        Dim currentHostValue As String = String.Empty

        Dim currentRequestOrigin = currentRequest.Headers("Origin")
        Dim currentRequestHost = currentRequest.Headers("Host")

        Dim currentRequestHeaders = currentRequest.Headers("Access-Control-Request-Headers")
        Dim currentRequestMethod = currentRequest.Headers("Access-Control-Request-Method")

        If currentRequestOrigin IsNot Nothing Then
            currentOriginValue = currentRequestOrigin
        End If

        If currentRequest.Path.ToLower().IndexOf("token") > -1 Or Request.HttpMethod = "OPTIONS" Then
            currentResponse.Headers.Remove("Access-Control-Allow-Origin")
            currentResponse.AppendHeader("Access-Control-Allow-Origin", "*")
        End If

        For Each key In Request.Headers.AllKeys
            If key = "Origin" AndAlso Request.HttpMethod = "OPTIONS" Then
                currentResponse.AppendHeader("Access-Control-Allow-Credentials", "true")
                currentResponse.AppendHeader("Access-Control-Allow-Methods", currentRequestMethod)
                currentResponse.AppendHeader("Access-Control-Allow-Headers", If(currentRequestHeaders, "GET,POST,PUT,DELETE,OPTIONS"))
                currentResponse.StatusCode = 200
                currentResponse.End()
            End If
        Next

    End Sub

Ici, ce code autorise uniquement le pré-vol et la demande de jeton d'ajouter "Access-Control-Allow-Origin" dans la réponse sinon je ne l'ajoute pas.

Voici mon blog sur la mise en œuvre: https://ibhowmick.wordpress.com/2018/09/21/cross-domain-token-based-authentication-with-web-api2-and-jquery-angular-5-angular- 6 /

indranil bhowmick
la source
0

pour ceux qui utilisent IIS avec php, sur IIS, mettez à jour le fichier web.config côté serveur dans le répertoire racine (wwwroot) et ajoutez ceci

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <system.webServer>
        <directoryBrowse enabled="true" />
        <httpProtocol>
            <customHeaders>
                <add name="Control-Allow-Origin" value="*"/>
            </customHeaders>
        </httpProtocol>
    </system.webServer>
</configuration>

après cela, redémarrez le serveur IIS, tapez IISReset dans RUN et entrez

user889030
la source
0

Voici une autre instance similaire aux exemples ci-dessus où vous ne pouvez avoir qu'un seul fichier de configuration pour définir où se trouve CORS: il y avait deux fichiers web.config sur le serveur IIS sur le chemin dans différents répertoires, et l'un d'eux était caché dans le répertoire virtuel. Pour le résoudre, j'ai supprimé le fichier de configuration de niveau racine car le chemin utilisait le fichier de configuration dans le répertoire virtuel. Il faut choisir l'un ou l'autre.

URL called:  'https://example.com/foo/bar'
                     ^              ^
      CORS config file in root      virtual directory with another CORS config file
          deleted this config             other sites using this

Cliff Coulter
la source
0

L'en-tête "Access-Control-Allow-Origin" contient plusieurs valeurs

quand j'ai reçu cette erreur, j'ai passé des tonnes d'heures à chercher une solution mais rien ne fonctionne, enfin j'ai trouvé une solution à ce problème qui est très simple. lorsque l'en-tête `` Access-Control-Allow-Origin '' a été ajouté plus d'une fois à votre réponse, cette erreur se produit, vérifiez votre apache.conf ou httpd.conf (serveur Apache), script côté serveur, et supprimez l'en-tête d'entrée indésirable de ces fichiers .

Jiten Mhatre
la source