O cabeçalho 'Access-Control-Allow-Origin' contém vários valores

104

Estou usando AngularJS $ http no lado do cliente para acessar um ponto de extremidade de um aplicativo ASP.NET Web API no lado do servidor. Como o cliente está hospedado em um domínio diferente do servidor, preciso do CORS. Ele funciona para $ http.post (url, dados). Mas assim que eu autentico o usuário e faço uma solicitação via $ http.get (url), recebo a mensagem

O cabeçalho 'Access-Control-Allow-Origin' contém vários valores 'http://127.0.0.1:9000, http://127.0.0.1:9000', mas apenas um é permitido. Origem 'http://127.0.0.1:9000', portanto, não tem acesso permitido.

O Fiddler me mostra que há realmente duas entradas de cabeçalho na solicitação get após uma solicitação de opções bem-sucedida. O que e onde estou fazendo algo errado?

Atualizar

Quando eu uso jQuery $ .get em vez de $ http.get, a mesma mensagem de erro aparece. Portanto, isso não parece ser um problema com o AngularJS. Mas onde está errado?

Papa Mufflon
fonte
Bem, o que contém o cabeçalho?
eckes

Respostas:

53

Eu adicionei

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

assim como

app.UseCors(CorsOptions.AllowAll);

no servidor. Isso resulta em duas entradas de cabeçalho. Basta usar o último e funciona.

Papa Mufflon
fonte
4
Parece que você está lendo Properties.Settings.Default.Cors de um arquivo de configurações. Você pode postar um exemplo? E em que classe o UseCors está?
Hoppe
"ReferenceError não capturado: EnableCorsAttribute não está definido" ??
circuito de
@Hoppe, dê uma olhada em msdn.microsoft.com/en-us/library/dn314597(v=vs.118).aspx . Isso explica que o primeiro parâmetro do EnableCorsAttribute são as origens permitidas. Por exemplo, "*" para permitir todos.
Papa Mufflon
1
@Hoppe, UseCors é um método de extensão definido no pacote NuGet Microsoft.Owin.Cors. Sf katanaproject.codeplex.com/SourceControl/latest#src/… .
Papa Mufflon
7
config.EnableCors (enableCorsAttribute) é geralmente chamado em WebApiConfig.cs - faz parte do pacote Microsoft.AspNet.WebApi.Cors Nuget, cujo uso é descrito aqui: asp.net/web-api/overview/security/… app .UseCors (CorsOptions.AllowAll) geralmente é chamado em Startup.Auth.cs como parte da configuração de seu provedor de identidade (por exemplo, OAuth) e faz parte do pacote Microsoft.Owin.Cors Nuget.
Henry C
51

Encontramos esse problema porque configuramos o CORS de acordo com a prática recomendada (por exemplo, http://www.asp.net/web-api/overview/security/enabling-cross-origin-requests-in-web-api ) E TAMBÉM tinha um cabeçalho personalizado <add name="Access-Control-Allow-Origin" value="*"/>em web.config.

Remova a entrada web.config e tudo ficará bem.

Ao contrário da resposta de @mww, ainda temos EnableCors()no WebApiConfig.cs E um EnableCorsAttributeno controlador. Quando eliminamos um ou outro, encontramos outros problemas.

Brandon Kuczenski
fonte
11
Removi esta linha <add name = "Access-Control-Allow-Origin" value = "*" /> e tinha as seguintes outras duas entradas no arquivo web.config que não removi: <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 é a chave, você só deve habilitar o CORS uma vez, meu problema era que eu também tinha habilitado no meu web.config assim como no app.UseCors () ... Eu removi a entrada web.config e apenas usei o app.UseCors (Microsoft.Owin.Cors.CorsOptions.AllowAll); método em vez disso.
Mohammad Sepahvand
1
A linha acima salvou minha vida! Certifique-se de não habilitar o CORS mais de uma vez, caso contrário, isso acontecerá e você ficará muito frustrado.
TGarrett
removeu o <add name = "Access-Control-Allow-Headers" value = "Content-Type" /> do web.config e corrigiu para mim
jbooker
1
"Esta é a chave, você deve habilitar o CORS apenas uma vez" <- ISSO É @MohammadSepahvand OBRIGADO. De volta ao .NET e já pego surpreso: D.
Tuan Jinn
42

Estou usando Cors 5.1.0.0, depois de muita dor de cabeça, descobri que o problema era duplicar os cabeçalhos Access-Control-Allow-Origin e Access-Control-Allow-Header do servidor

Removido config.EnableCors() do arquivo WebApiConfig.cs e apenas definido o [EnableCors("*","*","*")]atributo na classe Controller

Verifique este artigo para mais detalhes.

mww
fonte
isso funciona para mim, apenas certifique-se de que você não está definindo outro como este <add name = "Access-Control-Allow-Origin" value = "*" /> em web.config
Crismograma de
12

Adicionar para registrar 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>

MAS NÃO AMBOS

tfa
fonte
2
Esta foi a solução chave para mim, não faça as duas coisas.
robnick
8

Na verdade, você não pode definir vários cabeçalhos Access-Control-Allow-Origin(ou pelo menos não funcionará em todos os navegadores). Em vez disso, você pode definir condicionalmente uma variável de ambiente e usá-la na Headerdiretiva:

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

Portanto, neste exemplo, o cabeçalho de resposta será adicionado apenas se um cabeçalho de solicitação Origincorresponder a RegExp: ^(https?://localhost|https://[a-z]+\.my\.base\.domain)$(basicamente significa localhost sobre HTTP ou HTTPS e * .my.base.domain sobre HTTPS).

Lembre-se de habilitar o setenvifmódulo.

Docs:

BTW. O }ein %{ORIGIN_SUB_DOMAIN}enão é um erro de digitação. É como você usa a variável de ambiente na Headerdiretiva.

Nux
fonte
1
Você tem uma fonte para não definir vários cabeçalhos de controle de acesso? Não consigo encontrar nada que confirme isso.
Spencer
Solução muito inteligente e limpa. Funcionou para mim.
Alex Kalmikov
@Spencer "Nota: Na prática, a produção origin-list-or-null é mais restrita. Em vez de permitir uma lista de origens separadas por espaço, é uma única origem ou a string" null " ." w3.org/TR/cors/#access-control-allow-origin-response-header
Nux
8

Eu também tinha OWIN e meu WebAPI que aparentemente precisavam do CORS habilitado separadamente, o que por sua vez criou o 'Access-Control-Allow-Origin' header contains multiple values erro.

Acabei removendo TODOS os códigos que ativavam o CORS e adicionei o seguinte ao system.webServernó do meu 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>

Fazer isso satisfazia os requisitos de CORS para OWIN (permitindo login) e para WebAPI (permitindo chamadas de API), mas criou um novo problema: um OPTIONSmétodo não pôde ser encontrado durante a comprovação para minhas chamadas de API. A correção para isso foi simples - eu só precisava remover o seguinte do handlersnó do meu Web.Config:

<remove name="OPTIONSVerbHandler" />

Espero que isso ajude alguém.

Matt Cashatt
fonte
7

Servidor Apache:

Eu gastei o mesmo, mas foi porque eu não tinha aspas (") o asterisco em meu arquivo que fornecia acesso ao servidor, por exemplo '.htaccess.':

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

Você também pode ter um arquivo '.htaccess' em uma pasta com outro '.htaccess', por exemplo

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

No seu caso, em vez de '*' asterisco seria o ip (http://127.0.0.1:9000 servidor ) que você dá permissão para servir os dados.

ASP.NET:

Verifique se não há duplicata 'Access-Control-Allow-Origin' em seu código.

Ferramentas de desenvolvimento:

Com o Chrome, você pode verificar seus cabeçalhos de solicitação. Pressione a tecla F12 e vá até a aba 'Rede', agora execute a solicitação AJAX e aparecerá na lista, clique e dê todas as informações ali.

Access-Control-Allow-Origin: *

Chofoteddy
fonte
Às vezes é tão fácil ... Enquanto tentava fazer com que aquele serviço web confuso rodasse no IIS / Chrome, brinquei com o método Application_BeginRequest e esqueci ... duplicação em meu próprio código! Obrigado por me apontar para o óbvio! :)
Juergen Riemer
2
Para obter os cabeçalhos de resposta do CORS, você também terá que simular uma solicitação real de origem cruzada, portanto, ela pode não aparecer se você apenas olhar na guia rede no site em execução. No entanto, usar algo como DHC ( chrome.google.com/webstore/detail/dhc-resthttp-api-client/… ) para executar sua solicitação AJAX estará tecnicamente chamando de um domínio diferente, acionando CORS e permitindo que você veja os cabeçalhos de controle de acesso.
Henry C
4

Isso acontece quando você tem a opção Cors configurada em vários locais. No meu caso, eu o tinha no nível do controlador, bem como no Startup.Auth.cs / ConfigureAuth.

Pelo que entendi, se você quiser que ele se aplique em todo o aplicativo, basta configurá-lo em Startup.Auth.cs / ConfigureAuth assim ... Você precisará de referência a Microsoft.Owin.Cors

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

Se você preferir mantê-lo no nível do controlador, pode apenas inseri-lo no nível do controlador.

[EnableCors("http://localhost:24589", "*", "*")]
    public class ProductsController : ApiController
    {
        ProductRepository _prodRepo;
Nizar
fonte
No meu caso, coloquei-o em Web.Config e em MyAppApiConfig.cs. Removê-lo do último resolveu o problema para mim.
Jim B
4

se você estiver no IIS, você precisa ativar o CORS em web.config, então não precisa habilitar no método App_Start / WebApiConfig.cs Register

Minha solução foi, comentei as falas aqui:

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

e escreva no web.config:

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

freeeveloper
fonte
2

Isso também pode acontecer, é claro, se você realmente definiu seu Access-Control-Allow-Origincabeçalho para ter vários valores - por exemplo, uma lista de valores separados por vírgulas, que é meio que compatível com o RFC, mas não é realmente compatível com a maioria dos navegadores principais. Observe que a RFC fala sobre como permitir mais de um domínio sem usar '*' também.

Por exemplo, você pode obter esse erro no Chrome usando um cabeçalho como este:

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

Isto estava em Chrome Version 64.0.3282.186 (Official Build) (64-bit)

Observe que se você está considerando isso por causa de um CDN e usa a Akamai, pode querer observar que a Akamai não armazenará em cache no servidor se você usar Vary:Origin , da maneira que muitos sugerem para resolver esse problema.

Você provavelmente terá que alterar a forma como sua chave de cache é construída, usando um comportamento de resposta "Cache ID Modification". Mais detalhes sobre este problema nesta questão StackOverflow relacionada

Brad Parks
fonte
Então, basicamente, você não pode agora, porque é duvidoso que você deseje que todos os domínios da Internet acessem a url.
scottheckel
O link da Akamai precisa estar logado.
Jean-François Savard
sim, parece ser um requisito akamai para esses documentos ;-(
Brad Parks,
Outra maneira de obter esse erro no Chrome é com uma lista separada por espaços de valores: Access-Control-Allow-Origin: http://test.mysite.com http://test2.mysite.com. Essa seria a maneira correta, mas os navegadores não seguem o padrão aqui ( fonte ).
tanius de
2

Tão estúpido e simples:

Este problema ocorreu para mim ao ter duas vezes Header always set Access-Control-Allow-Origin *dentro do meu arquivo de configuração do Apache. Uma vez dentro das VirtualHosttags e uma vez dentro da Limittag:

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

Remover uma entrada resolveu o problema.

Acho que na postagem original teria sido duas vezes:

Header set Access-Control-Allow-Origin: "http://127.0.0.1:9000"
Wilt
fonte
1

só tive esse problema com um servidor nodejs.

aqui está como eu consertei.
Eu executo meu servidor de nó através de um nginx proxye eu defini nginx e nodepara ambos allow cross domain requestse ele não gostou, então eu o removi do nginx e o deixei no nó e tudo estava bem.

James Harrington
fonte
Obrigado por esta resposta! Ele resolveu um problema que eu não conseguia resolver há muito tempo com uma configuração nginx + Rack (Ruby). Mesmo problema, mesma solução: desative as adições de cabeçalho no nginx e deixe o rack-corsgem lidar com as coisas do CORS. Bam, consertado.
Pistos
0

Eu enfrentei o mesmo problema e isso é o que fiz para resolvê-lo:

No serviço WebApi, dentro de Global.asax, escrevi o seguinte 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

Aqui, este código permite apenas a solicitação de pré-voo e de token para adicionar "Access-Control-Allow-Origin" na resposta, caso contrário, não o estou adicionando.

Aqui está meu blog sobre a implementação: https://ibhowmick.wordpress.com/2018/09/21/cross-domain-token-based-authentication-with-web-api2-and-jquery-angular-5-angular- 6 /

indranil bhowmick
fonte
0

para aqueles que estão usando IIS com php, no IIS, atualize o arquivo web.config do lado do servidor no diretório raiz (wwwroot) e adicione este

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

depois disso reinicie o servidor IIS, digite IISReset em RUN e digite

user889030
fonte
0

Aqui está outra instância semelhante aos exemplos acima, em que você pode ter apenas um arquivo de configuração para definir onde está o CORS: Havia dois arquivos web.config no servidor IIS no caminho em diretórios diferentes e um deles estava oculto no diretório virtual. Para resolver isso, apaguei o arquivo de configuração do nível raiz, pois o caminho estava usando o arquivo de configuração no diretório virtual. Tem que escolher um ou outro.

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
fonte
0

O cabeçalho 'Access-Control-Allow-Origin' contém vários valores

Quando recebi esse erro, passei muitas horas procurando a solução para isso, mas nada funciona, finalmente encontrei a solução para esse problema que é muito simples. quando o cabeçalho '' Access-Control-Allow-Origin 'for adicionado mais de uma vez à sua resposta, este erro ocorrer, verifique seu apache.conf ou httpd.conf (servidor Apache), o script do lado do servidor e remova o cabeçalho de entrada indesejado desses arquivos .

Jiten Mhatre
fonte