El encabezado 'Access-Control-Allow-Origin' contiene varios valores

104

Estoy usando AngularJS $ http en el lado del cliente para acceder a un punto final de una aplicación ASP.NET Web API en el lado del servidor. Como el cliente está alojado en un dominio diferente al del servidor, necesito CORS. Funciona para $ http.post (url, data). Pero tan pronto como autentico al usuario y hago una solicitud a través de $ http.get (url), recibo el mensaje

El encabezado 'Access-Control-Allow-Origin' contiene varios valores 'http://127.0.0.1:9000, http://127.0.0.1:9000', pero solo se permite uno. Por lo tanto, no se permite el acceso al origen 'http://127.0.0.1:9000'.

Fiddler me muestra que, de hecho, hay dos entradas de encabezado en la solicitud de obtención después de una solicitud de opciones exitosa. ¿Qué y dónde estoy haciendo algo mal?

Actualizar

Cuando uso jQuery $ .get en lugar de $ http.get, aparece el mismo mensaje de error. Así que esto no parece ningún problema con AngularJS. Pero, ¿dónde está mal?

Papa Mufflon
fuente
Bueno, ¿qué contiene el encabezado?
eckes

Respuestas:

53

yo añadí

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

tanto como

app.UseCors(CorsOptions.AllowAll);

en el servidor. Esto da como resultado dos entradas de encabezado. Solo usa el último y funciona.

Papa Mufflon
fuente
4
Parece que está leyendo Properties.Settings.Default.Cors desde un archivo de configuración. Puede publicar un ejemplo? ¿Y en qué clase está UseCors?
Hoppe
"Error de referencia no detectado: EnableCorsAttribute no está definido" ??
Circuito
@Hoppe, eche un vistazo a msdn.microsoft.com/en-us/library/dn314597(v=vs.118).aspx . Explica que el primer parámetro de EnableCorsAttribute son los orígenes permitidos. Por ejemplo, "*" para permitir todos.
Papa Mufflon
1
@Hoppe, UseCors es un método de extensión definido en el paquete NuGet Microsoft.Owin.Cors. Sf katanaproject.codeplex.com/SourceControl/latest#src/… .
Papa Mufflon
7
config.EnableCors (enableCorsAttribute) generalmente se llama en WebApiConfig.cs; es parte del paquete Microsoft.AspNet.WebApi.Cors Nuget, cuyo uso se describe aquí: asp.net/web-api/overview/security/… app .UseCors (CorsOptions.AllowAll) generalmente se llama en Startup.Auth.cs como parte de la configuración de su proveedor de identidad (por ejemplo, OAuth) y es parte del paquete Microsoft.Owin.Cors Nuget.
Henry C
51

Nos encontramos con este problema porque habíamos configurado CORS de acuerdo con las mejores prácticas (por ejemplo, http://www.asp.net/web-api/overview/security/enabling-cross-origin-requests-in-web-api ) Y TAMBIÉN tenía un encabezado personalizado <add name="Access-Control-Allow-Origin" value="*"/>en web.config.

Elimine la entrada web.config y todo estará bien.

Al contrario de la respuesta de @ mww, todavía tenemos EnableCors()en WebApiConfig.cs Y un EnableCorsAttributeen el controlador. Cuando sacamos uno u otro, nos encontramos con otros problemas.

Brandon Kuczenski
fuente
11
Eliminé esta línea <add name = "Access-Control-Allow-Origin" value = "*" /> y tenía las otras dos entradas siguientes en el archivo web.config que no eliminé: <add name = "Access -Control-Allow-Headers "value =" Content-Type "/> <add name =" Access-Control-Allow-Methods "value =" GET, POST, PUT, DELETE, OPTIONS "/>
Siva Karthikeyan
2
Esta es la clave, solo debe habilitar CORS una vez, mi problema fue que también lo tenía habilitado en mi web.config y en app.UseCors () ... Eliminé la entrada web.config y solo usé la aplicación.UseCors (Microsoft.Owin.Cors.CorsOptions.AllowAll); método en su lugar.
Mohammad Sepahvand
1
¡La línea de arriba me salvó la vida! Asegúrese de no habilitar CORS más de una vez, de lo contrario esto sucederá y se sentirá muy frustrado.
TGarrett
eliminó el <add name = "Access-Control-Allow-Headers" value = "Content-Type" /> de web.config y lo solucionó para mí
jbooker
1
"Esta es la clave, solo debe habilitar CORS una vez" <- ESTO ES @MohammadSepahvand GRACIAS. De vuelta a .NET y ya me sorprendió: D.
Tuan Jinn
42

Estoy usando Cors 5.1.0.0, después de mucho dolor de cabeza, descubrí que el problema estaba duplicado en los encabezados Access-Control-Allow-Origin y Access-Control-Allow-Header del servidor

Eliminado config.EnableCors()del archivo WebApiConfig.cs y simplemente establezca el [EnableCors("*","*","*")]atributo en la clase Controller

Consulte este artículo para obtener más detalles.

mww
fuente
esto funciona para mí, solo asegúrese de que no esté configurando otro como este <add name = "Access-Control-Allow-Origin" value = "*" /> en web.config
Crismogram
12

Agregar para registrar WebApiConfig

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

O 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>

PERO NO AMBOS

tfa
fuente
2
Esta fue la solución clave para mí, no hagas ambas cosas.
robnick
8

En realidad, no puede establecer varios encabezados Access-Control-Allow-Origin(o al menos no funcionará en todos los navegadores). En su lugar, puede establecer condicionalmente una variable de entorno y luego usarla en la Headerdirectiva:

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

Entonces, en este ejemplo, el encabezado de respuesta se agregará solo si un encabezado de solicitud Origincoincide con RegExp: ^(https?://localhost|https://[a-z]+\.my\.base\.domain)$(básicamente significa localhost sobre HTTP o HTTPS y * .my.base.domain sobre HTTPS).

Recuerde habilitar el setenvifmódulo.

Documentos:

Por cierto. El }een %{ORIGIN_SUB_DOMAIN}eque no es un error tipográfico. Es cómo se usa la variable de entorno en la Headerdirectiva.

Nux
fuente
1
¿Tiene una fuente para no configurar varios encabezados de control de acceso? No puedo encontrar nada que confirme esto.
Spencer
Solución muy inteligente y limpia. Trabajó para mi.
Alex Kalmikov
@Spencer "Nota: En la práctica, la producción de lista de origen o nulo está más restringida. En lugar de permitir una lista de orígenes separada por espacios, es un origen único o la cadena" nula "" . w3.org/TR/cors/#access-control-allow-origin-response-header
Nux
8

Yo también tenía tanto OWIN como mi WebAPI que aparentemente necesitaban CORS habilitado por separado, lo que a su vez creó el 'Access-Control-Allow-Origin' header contains multiple valueserror.

Terminé eliminando TODO el código que habilitó CORS y luego agregué lo siguiente al system.webServernodo de mi 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>

Hacer esto satisfizo los requisitos de CORS para OWIN (permitir el inicio de sesión) y para WebAPI (permitir llamadas a la API), pero creó un nuevo problema: OPTIONSno se pudo encontrar un método durante la verificación previa para mis llamadas a la API. La solución fue simple: solo necesitaba eliminar lo siguiente del handlersnodo my Web.Config:

<remove name="OPTIONSVerbHandler" />

Espero que esto ayude a alguien.

Matt Cashatt
fuente
7

Servidor Apache:

Gasto lo mismo, pero fue porque no tenía comillas (") el asterisco en mi archivo que proporcionaba acceso al servidor, por ejemplo, '.htaccess.':

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

También puede tener un archivo '.htaccess' en una carpeta con otro '.htaccess', por ejemplo

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

En su caso, en lugar de '*', el asterisco sería el http://127.0.0.1:9000servidor ip ( ) al que da permiso para servir datos.

ASP.NET:

Verifique que no haya un duplicado 'Access-Control-Allow-Origin' en su código.

Herramientas de desarrollo:

Con Chrome puede verificar los encabezados de sus solicitudes. Presione la tecla F12 y vaya a la pestaña 'Red', ahora ejecute la solicitud AJAX y aparecerá en la lista, haga clic y dé toda la información que está allí.

Acceso-Control-Permitir-Origen: *

Chofoteddy
fuente
A veces es así de fácil ... Mientras intentaba que esos servicios web confusos se ejecutaran en IIS / Chrome, jugué con el método Application_BeginRequest y me olvidé de él ... ¡duplicación en mi propio código! ¡Gracias por señalarme lo obvio! :)
Juergen Riemer
2
Para obtener los encabezados de respuesta de CORS, también tendrá que simular una solicitud de origen cruzado real, por lo que es posible que no aparezca si solo mira en la pestaña de red en el sitio en ejecución. Sin embargo, usar algo como DHC ( chrome.google.com/webstore/detail/dhc-resthttp-api-client/… ) para ejecutar su solicitud AJAX será técnicamente llamar desde un dominio diferente, lo que activará CORS y le permitirá ver los encabezados de Control de acceso.
Henry C
4

Esto sucede cuando tiene la opción Cors configurada en varias ubicaciones. En mi caso lo tenía tanto a nivel de controlador como en Startup.Auth.cs / ConfigureAuth.

Tengo entendido que si lo desea para toda la aplicación, configúrelo en Startup.Auth.cs / ConfigureAuth de esta manera ... Necesitará una referencia a Microsoft.Owin.Cors

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

Si prefiere mantenerlo en el nivel del controlador, puede insertarlo en el nivel del controlador.

[EnableCors("http://localhost:24589", "*", "*")]
    public class ProductsController : ApiController
    {
        ProductRepository _prodRepo;
Nizar
fuente
En mi caso, lo tenía configurado tanto en Web.Config como en MyAppApiConfig.cs. Quitarlo de este último resolvió el problema para mí.
Jim B
4

si está en IIS, necesita activar CORS en web.config, entonces no necesita habilitarlo en App_Start / WebApiConfig.cs método de registro

Mi solución fue, comentaron las líneas aquí:

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

y escriba en web.config:

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

desarrollador libre
fuente
2

Esto también puede suceder, por supuesto, si realmente ha configurado su Access-Control-Allow-Originencabezado para que tenga varios valores, por ejemplo, una lista de valores separados por comas, que es compatible con el RFC, pero en realidad no es compatible con la mayoría de los navegadores principales. Tenga en cuenta que el RFC habla sobre cómo permitir más de un dominio sin usar '*' también.

Por ejemplo, puede obtener ese error en Chrome usando un encabezado como este:

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

Esto fue en Chrome Version 64.0.3282.186 (Official Build) (64-bit)

Tenga en cuenta que si está considerando esto debido a una CDN y usa Akamai, es posible que desee tener en cuenta que Akamai no almacenará en caché en el servidor si lo usa Vary:Origin , como muchos sugieren para resolver este problema.

Probablemente tendrá que cambiar la forma en que se construye su clave de caché, utilizando un comportamiento de respuesta de "Modificación de ID de caché". Más detalles sobre este problema en esta pregunta relacionada de StackOverflow

Brad Parks
fuente
Básicamente, no puede en este momento porque es dudoso que desee que todos los dominios de Internet accedan a la URL.
scottheckel
El enlace de Akamai requiere iniciar sesión.
Jean-François Savard
sí, eso parece ser un requisito de akamai para esos documentos ;-(
Brad Parks
Otra forma de obtener este error en Chrome es una lista separada por espacios de valores: Access-Control-Allow-Origin: http://test.mysite.com http://test2.mysite.com. Esa sería la forma correcta, pero los navegadores no siguen el estándar aquí ( fuente ).
tanius
2

Tan estúpido y simple:

Este problema me ocurrió cuando tenía dos tiempos Header always set Access-Control-Allow-Origin *dentro de mi archivo de configuración de Apache. Una vez dentro de las VirtualHostetiquetas y una vez dentro de una Limitetiqueta:

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

Eliminar una entrada resolvió el problema.

Supongo que en la publicación original habría sido dos veces:

Header set Access-Control-Allow-Origin: "http://127.0.0.1:9000"
Marchitar
fuente
1

Acabo de tener este problema con un servidor nodejs.

así es como lo arreglé.
Ejecuté mi servidor de nodo a través de nginx proxyay configuré nginx y nodea ambos allow cross domain requestsy no me gustó, así que lo eliminé de nginx y lo dejé en el nodo y todo estuvo bien.

James Harrington
fuente
¡Gracias por esta respuesta! Resolvió un problema que no pude resolver durante mucho tiempo con una configuración de nginx + Rack (Ruby). El mismo problema, la misma solución: desactive las adiciones de encabezado en nginx y deje que la rack-corsgema maneje las cosas de CORS. Bam, arreglado.
Pistos
0

Me he enfrentado al mismo problema y esto es lo que hice para resolverlo:

En el servicio WebApi, dentro de Global.asax he escrito el siguiente código:

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

Aquí este código solo permite la solicitud previa al vuelo y el token para agregar "Access-Control-Allow-Origin" en la respuesta; de lo contrario, no lo agregaré.

Aquí está mi blog sobre la implementación: https://ibhowmick.wordpress.com/2018/09/21/cross-domain-token-based-authentication-with-web-api2-and-jquery-angular-5-angular- 6 /

indranil bhowmick
fuente
0

para aquellos que están usando IIS con php, en el lado del servidor de IIS, actualice el archivo web.config, el directorio raíz (wwwroot) y agregue esto

<?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>

después de eso, reinicie el servidor IIS, escriba IISReset en RUN e ingrese

user889030
fuente
0

Aquí hay otra instancia similar a los ejemplos anteriores en la que solo puede tener un archivo de configuración que defina dónde está CORS: había dos archivos web.config en el servidor IIS en la ruta en diferentes directorios, y uno de ellos estaba oculto en el directorio virtual. Para resolverlo, eliminé el archivo de configuración de nivel raíz ya que la ruta usaba el archivo de configuración en el directorio virtual. Tienes que elegir uno u otro.

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

Coulter acantilado
fuente
0

El encabezado 'Access-Control-Allow-Origin' contiene varios valores

Cuando recibí este error, pasé toneladas de horas buscando una solución para esto, pero nada funciona, finalmente encontré una solución a este problema que es muy simple. cuando el encabezado '' Access-Control-Allow-Origin 'se agrega más de una vez a su respuesta, se produce este error, verifique su apache.conf o httpd.conf (servidor Apache), el script del lado del servidor y elimine el encabezado de entrada no deseado de estos archivos .

Jiten Mhatre
fuente