A resposta à solicitação de comprovação não passa na verificação de controle de acesso

458

Estou recebendo este erro usando o ngResource para chamar uma API REST no Amazon Web Services:

XMLHttpRequest não pode carregar http://server.apiurl.com:8000/s/login?login=facebook . A resposta à solicitação de comprovação não passa na verificação do controle de acesso: Nenhum cabeçalho 'Access-Control-Allow-Origin' está presente no recurso solicitado. Portanto, a origem ' http: // localhost ' não é permitida. Erro 405

Serviço:

socialMarkt.factory('loginService', ['$resource', function($resource){    
    var apiAddress = "http://server.apiurl.com:8000/s/login/";
    return $resource(apiAddress, { login:"facebook", access_token: "@access_token" ,facebook_id: "@facebook_id" }, {
                getUser: {method:'POST'}
            });
}]);

Controlador:

[...]
loginService.getUser(JSON.stringify(fbObj)),
                function(data){
                    console.log(data);
                },
                function(result) {
                    console.error('Error', result.status);
                }
[...]

Estou usando o Chrome e não sei mais o que fazer para corrigir esse problema. Eu até configurei o servidor para aceitar cabeçalhos de origem localhost.

Andre Mendes
fonte
confuso: você "configurou o servidor" ou é "uma API de descanso no serviço da web amazon"?
Dandavis
3
Você claramente não fez o suficiente para ativar o CORS no lado do servidor. Postar amostra de cabeçalhos de resposta
charlietfl 23/02
4
De qualquer maneira, seus votos negativos estão errados. Ele está hospedando seus arquivos em sua máquina local. Não importa que tipo de confusão ele faz no back-end. Angular não permitirá este pré voo.
E. Maggini 23/02
3
Thx pelos comentários, funcionou quando configurei o navegador para ativar a segurança #
Andre Mendes
1
@Andre Mas desligar de segurança é apenas uma solução feio onde são comprometer a segurança, does not resolver o seu problema ...
Shivi

Respostas:

240

Você está tendo problemas com o CORS.

Existem várias maneiras de corrigir / solucionar isso.

  1. Desligue o CORS. Por exemplo: como desativar cors no chrome
  2. Use um plugin para o seu navegador
  3. Use um proxy como o nginx. exemplo de como configurar
  4. Siga a configuração necessária para o seu servidor. Esse é mais um fator do servidor da web que você carregou na instância do EC2 (presumindo que isso seja o que você quer dizer com "Amazon web service"). Para seu servidor específico, você pode consultar o site ativar o CORS.

Mais detalhadamente, você está tentando acessar api.serverurl.com a partir do localhost. Esta é a definição exata de solicitação entre domínios.

Ao desativá-lo apenas para concluir seu trabalho (OK, coloque pouca segurança para você se você visitar outros sites e apenas abrir a lata no caminho), você pode usar um proxy que faz o navegador pensar que todas as solicitações vêm do host local quando realmente você tem um servidor local que chama o servidor remoto.

portanto, api.serverurl.com pode se tornar localhost: 8000 / api e seu nginx local ou outro proxy será enviado para o destino correto.


Agora, por demanda popular, 100% mais informações sobre o CORS .... o mesmo bom gosto!


E para os que recusam ... ignorar o CORS é exatamente o que é mostrado para aqueles que simplesmente aprendem o front-end. https://codecraft.tv/courses/angular/http/http-with-promises/

E. Maggini
fonte
776
deixado de fora o óbvio de CORS execução corretamente
charlietfl
40
É fácil votar abaixo. Menos fácil de se arriscar, meu amigo. E tudo isso funciona exatamente em um ambiente de desenvolvimento.
E. Maggini 23/02
3
Na verdade, funcionou. Eu adicionei o sinalizador para desativar a segurança da Web. Para o desenvolvimento é bom.
Andre Mendes
15
@charlietfl Como?
GreenAsJade
3
Obrigado você salvou meu dia. Utilizou apenas a primeira opção: C: \ Arquivos de programas (x86) \ Google \ Chrome \ Application> chrome.exe --user-data-dir = "C: \ Chrome dev session" --disable-web-security. De: stackoverflow.com/questions/3102819/…
Harsimer
169

Meu "API Server" é um aplicativo PHP. Para solucionar esse problema, encontrei a solução abaixo para funcionar:

Coloque as linhas em index.php

header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: GET, POST, PATCH, PUT, DELETE, OPTIONS');
header('Access-Control-Allow-Headers: Origin, Content-Type, X-Auth-Token');
Slipstream
fonte
3
Concordo, isso é melhor que a resposta aceita, embora tenha cuidado ao copiar essas linhas, certifique-se de modificar os métodos e a origem.
Amir Savand
11
Onde colocá-lo em um projeto Angular 6?
Whatthefish
@CodyBugstein e colocar whatthefish antes de qualquer saída
Garet Claborn
Meu aplicativo cliente parou de funcionar quando adicionei um cabeçalho necessário apenas para alguns servidores. Se a solicitação incluir cabeçalhos personalizados, eles deverão ser listados Access-Control-Allow-Headers.
Z0r 16/07/19
47

Na API da web do AspNetCore, esse problema foi corrigido adicionando "Microsoft.AspNetCore.Cors" (versão 1.1.1) e adicionando as alterações abaixo no Startup.cs.

public void ConfigureServices(IServiceCollection services)
{ 
    services.AddCors(options =>
    {
          options.AddPolicy("AllowAllHeaders",
                builder =>
            {
                    builder.AllowAnyOrigin()
                           .AllowAnyHeader()
                           .AllowAnyMethod();
                });
    });
    .
    .
    .
}

e

public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{


    // Shows UseCors with named policy.
    app.UseCors("AllowAllHeaders");
    .
    .
    .
}

e colocando [EnableCors("AllowAllHeaders")]o controlador.

Rajkumar Peter
fonte
18
Esta é uma boa resposta se você deseja criar vulnerabilidades de script entre sites! Por favor, nunca faça isso! Especifique seus domínios que você pode acessar para evitar problemas de segurança. O CORS está lá por uma razão.
paqogomez
2
Apenas para esclarecer @paqogomez, no seu método ConfigureServices: services.AddCors (options => {options.AddPolicy ("AllowSpecificOrigin", construtor => {builder.WithOrigins (" localhost" ) .AllowAnyOrigin () .AllowAnyHeader (). AllowAnyMethod ();});}); e no seu método Configure: app.UseCors ("AllowSpecificOrigin");
Francisco Tena
28

Existem algumas advertências quando se trata de CORS. Primeiro, ele não permite curingas* mas não me prenda a isso. Eu li em algum lugar e não consigo encontrar o artigo agora.

Se você estiver solicitando um domínio diferente, precisará adicionar os cabeçalhos de origem permitida.

 Access-Control-Allow-Origin: www.other.com 

Se você está fazendo solicitações que afetam os recursos do servidor, como POST / PUT / PATCH, e se o tipo MIME é diferente do seguinte application/x-www-form-urlencoded, multipart/form-dataou text/plaino navegador irá automaticamente fazer uma pre-flight OPÇÕES solicitar para verificar com o servidor se ele permitiria .

Portanto, sua API / servidor precisa lidar com essas solicitações OPTIONS de acordo. Você precisa responder com o access control headerscódigo de status de resposta HTTP apropriado e deve ser200 .

Os cabeçalhos devem ser algo assim, ajuste-os de acordo com suas necessidades:

   Access-Control-Allow-Methods: GET, POST, PUT, PATCH, POST, DELETE, OPTIONS
   Access-Control-Allow-Headers: Content-Type
   Access-Control-Max-Age: 86400

O cabeçalho de idade máxima é importante, no meu caso, não funcionaria sem ele, acho que o navegador precisa das informações por quanto tempo os "direitos de acesso" são válidos.

Além disso, se você estiver fazendo, por exemplo, uma POSTsolicitação com application/jsonmime de um domínio diferente, também precisará adicionar o cabeçalho de origem de permissão mencionado anteriormente, para que fique assim:

   Access-Control-Allow-Origin: www.other.com 
   Access-Control-Allow-Methods: GET, POST, PUT, PATCH, POST, DELETE, OPTIONS
   Access-Control-Allow-Headers: Content-Type
   Access-Control-Max-Age: 86400

Quando o pré-vôo for bem-sucedido e obtiver todas as informações necessárias, sua solicitação real será feita.

De um modo geral, quaisquer Access-Controlcabeçalhos solicitados na solicitação inicial ou pré-vôo devem ser fornecidos na resposta para que funcione.

Há um bom exemplo nos documentos MDN aqui neste link , e você também deve verificar esta postagem do SO

Sasa Blagojevic
fonte
1
Aqui está o artigo Mozilla falando sobre como você não pode usar curinga para origem coros: Ligação Então, aparentemente isso só se aplica quando se usa credenciais (se eu estou entendendo corretamente)
Helzgate
Estou usando curinga e enviando um token de portador para autorizar a solicitação e ela está funcionando bem, por isso não tenho certeza a que link eu forneci acima se refere a credenciais. Meu problema foi que, ao bulding minha política de CORS no .Net Core, não adicionei .AllowCredentials(). Depois de adicionar .AllowCredentials()tudo funcionou.
precisa saber é o seguinte
15

JavaScript XMLHttpRequest e Fetch seguem a política de mesma origem. Portanto, um aplicativo Web usando XMLHttpRequest ou Fetch pode fazer apenas solicitações HTTP para seu próprio domínio.

Fonte: https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS

Você deve enviar o cabeçalho HTTP de Controle de Acesso-Permissão-Origem: * do lado do servidor.

Se você estiver usando o Apache como seu servidor HTTP, poderá adicioná-lo ao seu arquivo de configuração do Apache assim:

<IfModule mod_headers.c>
    Header set Access-Control-Allow-Origin "*"
</IfModule>

Mod_headers é ativado por padrão no Apache, no entanto, convém garantir que ele seja ativado executando:

 a2enmod headers
Tadej
fonte
Onde posso encontrar meu arquivo de configuração do Apache?
Shubham Arya
@ShubhamArya no Linux Debian a localização padrão é:/etc/apache2/apache2.conf
Tadej
onde posso encontrá-lo no windows?
Shubham Arya
10

Se você está escrevendo uma extensão chrome

Você precisa adicionar manifest.jsonas permissões para seu (s) domínio (s).

"permissions": [
   "http://example.com/*",
   "https://example.com/*"
]
freedev
fonte
1
Além disso, verifique se você tem prefixo www
Vlas Bashynskyi
8

Se você estiver usando o servidor IIS por acaso. Você pode definir os cabeçalhos abaixo na opção Cabeçalhos de solicitação HTTP.

Access-Control-Allow-Origin:*
Access-Control-Allow-Methods: 'HEAD, GET, POST, PUT, PATCH, DELETE'
Access-Control-Allow-Headers: 'Origin, Content-Type, X-Auth-Token';

com tudo isso, receba etc., funcionará bem.

Sunil Kumar
fonte
5

No PHP você pode adicionar os cabeçalhos:

<?php
header ("Access-Control-Allow-Origin: *");
header ("Access-Control-Expose-Headers: Content-Length, X-JSON");
header ("Access-Control-Allow-Methods: GET, POST, PATCH, PUT, DELETE, OPTIONS");
header ("Access-Control-Allow-Headers: *");
...
atiruz
fonte
obrigado, funcionou para mim! em ambiente de testes e produção. Mesmo usando https: //
Jose Seie
1
@atiruz Obrigado pela solução. Isso funciona Quando adicionei a linha #header ("Access-Control-Expose-Headers: Content-Length, X-JSON");
Silambarasan RD
5

Para corrigir problemas de solicitações de origem cruzada em um aplicativo Node JS:

npm i cors

E basta adicionar as linhas abaixo ao app.js

let cors = require('cors')
app.use(cors())
Rohit Parte
fonte
3
isso só funciona em aplicativos expressas js, nem todos os aplicativos do nó
DrCord
3

No meu arquivo de configuração do Apache VirtualHost, adicionei as seguintes linhas:

Header always set Access-Control-Allow-Origin "*"
Header always set Access-Control-Allow-Methods "POST, GET, OPTIONS, DELETE, PUT"
Header always set Access-Control-Max-Age "1000"
Header always set Access-Control-Allow-Headers "x-requested-with, Content-Type, origin, authorization, accept, client-security-token"

RewriteEngine On
RewriteCond %{REQUEST_METHOD} OPTIONS
RewriteRule ^(.*)$ $1 [R=200,L]
abraços
fonte
3

Para aqueles que estão usando o Lambda Integrated Proxy com API Gateway . Você precisa configurar sua função lambda como se estivesse enviando suas solicitações diretamente, o que significa que a função deve configurar os cabeçalhos de resposta corretamente. (Se você estiver usando funções lambda personalizadas, isso será tratado pelo API Gateway.)

//In your lambda's index.handler():
exports.handler = (event, context, callback) => {
     //on success:
     callback(null, {
           statusCode: 200,
           headers: {
                "Access-Control-Allow-Origin" : "*"
           }
     }
}
Xu Chen
fonte
1
Eu também quero falar e mencionar uma grande pegadinha que eu não acho que os documentos da AWS. Digamos que você use o gateway da API para fazer proxy da sua função lambda e use alguma API nessa função lambda. Se essa API retornar um código de sucesso que não seja 200 e você não adicionou o código de sucesso que não seja 200 à resposta do método no gateway da API, você receberá um erro e não verá sua resposta bem-sucedida . Exemplos para isso: Sendgrid e Twilio têm códigos de sucesso que não são 200.
Stephen Tetreault
3

Eu acho que desabilitar o CORS do Chrome não é uma boa maneira , porque se você o estiver usando no iônico, certamente no Mobile Build a questão aumentará novamente.

Tão melhor para corrigir em seu back-end.

Antes de tudo No cabeçalho, você precisa definir

  • cabeçalho ('Access-Control-Allow-Origin: *');
  • header ('Header set Access-Control-Allow-Headers: "Origin, X-Requested With, Content-Type, Accept"');

E se a API estiver se comportando como GET e POST, ambos também serão definidos no cabeçalho -

if ($ _SERVER ['REQUEST_METHOD'] == 'OPÇÕES') {if (isset ($ _ SERVER ['HTTP_ACCESS_CONTROL_REQUEST_METHOD']))) cabeçalho ("Métodos de permissão de controle de acesso: GET, POST, OPTIONS");
if (isset ($ _ SERVER ['HTTP_ACCESS_CONTROL_REQUEST_HEADERS'])) cabeçalho ("Acesso-Controle-Permitir Cabeçalhos:
{$ _SERVER ['HTTP_ACCESS_CONTROL_REQUEST_HEADERS']}"); saída (0); }

Shubham Pandey
fonte
3

Uma causa muito comum desse erro pode ser que a API do host tenha mapeado a solicitação para um método http (por exemplo, PUT) e o cliente da API esteja chamando a API usando um método http diferente (por exemplo, POST ou GET)

Christian Nwafor
fonte
Eu estava implementando CORS corretamente no meu servidor, mas eu esqueci de adicionar o PUTmétodo
fguillen
3

Nossa equipe ocasionalmente vê isso usando Vue, axios e um C # WebApi. Adicionar um atributo de rota no terminal que você está tentando acessar o corrige.

[Route("ControllerName/Endpoint")]
[HttpOptions, HttpPost]
public IHttpActionResult Endpoint() { }
w00ngy
fonte
Não temos muita certeza do porquê. Ri muito. Se alguém me avisar!
w00ngy
1

Eu enfrentei esse problema quando o servidor DNS foi definido como 8.8.8.8 (google). Na verdade, o problema estava no roteador, meu aplicativo tentou se conectar ao servidor pelo google, não localmente (no meu caso particular). Eu removi o 8.8.8.8 e isso resolveu o problema. Sei que esses problemas foram resolvidos pelas configurações do CORS, mas talvez alguém tenha o mesmo problema que eu

Kirill Gusyatin
fonte
1

Estou usando o AWS sdk para uploads, depois de passar algum tempo pesquisando on-line, me deparei com esse tópico. Graças a @lsimoneau 45581857 , acontece exatamente o mesmo que estava acontecendo. Simplesmente apontei meu URL de solicitação para a região no meu bucket anexando a opção region e funcionou.

 const s3 = new AWS.S3({
 accessKeyId: config.awsAccessKeyID,
 secretAccessKey: config.awsSecretAccessKey,
 region: 'eu-west-2'  // add region here });
davyCode
fonte
0

As distribuições independentes do GeoServer incluem o servidor de aplicativos Jetty. Ative o compartilhamento de recursos de origem cruzada (CORS) para permitir que aplicativos JavaScript fora do seu domínio usem o GeoServer.

Remova o comentário do seguinte <filter>e <filter-mapping>de webapps / geoserver / WEB-INF / web.xml:

<web-app>
  <filter>
      <filter-name>cross-origin</filter-name>
      <filter-class>org.eclipse.jetty.servlets.CrossOriginFilter</filter-class>
  </filter>
  <filter-mapping>
      <filter-name>cross-origin</filter-name>
      <url-pattern>/*</url-pattern>
  </filter-mapping>
</web-app>
Yassine Ech-Charafi
fonte
Isso não adicionar antyhing para cabeçalho de resposta, por isso não funcionou
JollyRoger
1
não usando o GeoServer, mas este clipe me ajudou a conhecer as configurações que devo usar no aplicativo que está recebendo a chamada.
precisa saber é o seguinte
0

É fácil resolver esse problema com apenas algumas etapas, sem se preocupar com nada. Por favor, siga os passos para resolvê-lo.

  1. open ( https://www.npmjs.com/package/cors#enabling-cors-pre-flight )
  2. vá para instalação e copie o comando npm install cors para instalar via terminal do nó
  3. vá para Uso Simples (Ativar Todas as Solicitações do CORS) rolando. em seguida, copie e cole a declaração completa no seu projeto e execute-a ... isso funcionará com certeza .. copie o código do comentário e cole-o no app.js ou em qualquer outro projeto e tente ...
Rahul sah
fonte
1
var express = requer ('express') var cors = requer ('cor') var app = express () app.use (cors ()) app.get ('/ produtos /: id', função (req, res, próximo) {res.json ({msg: 'Isso é habilitado para CORS para todas as origens!'})}) app.listen (80, function () {console.log ('servidor da Web habilitado para CORS escutando na porta 80') )})
Rahul sah
-1

Algo que é muito fácil de perder ...

No Solution Explorer, clique com o botão direito do mouse em api-project. Na janela de propriedades, defina 'Autenticação Anônima' como Ativado !!!

Wes
fonte
-8

Desabilite a segurança do Chrome. Crie um atalho do Chrome com o botão direito do mouse -> propriedades -> destino, cole este "C: \ Arquivos de Programas (x86) \ Google \ Chrome \ Application \ chrome.exe" --disable-web-security --user -data-dir = "c: / chromedev"

Nithin
fonte