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?


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.


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.


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.


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


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.


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.


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: *


À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;

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>


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


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"

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.


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 /


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


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


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 .

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.