Esta resposta cobre muito terreno, por isso é dividida em três partes:
- Como usar um proxy CORS dar a volta “No Access-Control-Allow-Origin cabeçalho” problemas
- Como evitar o preflight do CORS
- Como corrigir os problemas do cabeçalho "Acesso-controle-permissão-origem" não deve ser o curinga
Como usar um proxy CORS dar a volta “No Access-Control-Allow-Origin cabeçalho” problemas
Se você não controlar o servidor, seu código JavaScript de front-end está enviando uma solicitação e o problema com a resposta desse servidor é apenas a falta do Access-Control-Allow-Origin
cabeçalho necessário , você ainda poderá fazer as coisas funcionarem - fazendo a solicitação por meio de um Proxy CORS. Para mostrar como isso funciona, primeiro, aqui está um código que não usa um proxy CORS:
const url = "https://example.com"; // site that doesn’t send Access-Control-*
fetch(url)
.then(response => response.text())
.then(contents => console.log(contents))
.catch(() => console.log("Can’t access " + url + " response. Blocked by browser?"))
O motivo pelo qual o catch
bloco é atingido é que o navegador impede que esse código acesse a resposta da qual ele volta https://example.com
. E a razão pela qual o navegador faz isso é que a resposta não possui o Access-Control-Allow-Origin
cabeçalho de resposta.
Agora, aqui está exatamente o mesmo exemplo, mas apenas com um proxy CORS adicionado em:
const proxyurl = "https://cors-anywhere.herokuapp.com/";
const url = "https://example.com"; // site that doesn’t send Access-Control-*
fetch(proxyurl + url) // https://cors-anywhere.herokuapp.com/https://example.com
.then(response => response.text())
.then(contents => console.log(contents))
.catch(() => console.log("Can’t access " + url + " response. Blocked by browser?"))
Nota: Se https://cors-anywhere.herokuapp.com estiver inativo ou indisponível quando você o experimentar, veja abaixo como implantar seu próprio servidor CORS Anywhere no Heroku em apenas 2-3 minutos.
O segundo trecho de código acima pode acessar a resposta com êxito, porque pegar o URL da solicitação e alterá-lo para https://cors-anywhere.herokuapp.com/https://example.com - apenas prefixando-o com o URL do proxy - causa o solicitação a ser feita através desse proxy, que então:
- Encaminha a solicitação para
https://example.com
.
- Recebe a resposta de
https://example.com
.
- Adiciona o
Access-Control-Allow-Origin
cabeçalho à resposta.
- Passa essa resposta, com esse cabeçalho adicionado, de volta ao código de front-end solicitante.
O navegador então permite que o código de front-end acesse a resposta, porque essa resposta com o Access-Control-Allow-Origin
cabeçalho da resposta é o que o navegador vê.
Você pode executar facilmente seu próprio proxy usando o código de https://github.com/Rob--W/cors-anywhere/ .
Você também pode implantar facilmente seu próprio proxy no Heroku em literalmente apenas 2-3 minutos, com 5 comandos:
git clone https://github.com/Rob--W/cors-anywhere.git
cd cors-anywhere/
npm install
heroku create
git push heroku master
Após a execução desses comandos, você terminará com seu próprio servidor CORS Anywhere em execução, por exemplo, em https://cryptic-headland-94862.herokuapp.com/ . Portanto, em vez de prefixar seu URL de solicitação https://cors-anywhere.herokuapp.com
, prefixe-o com o URL da sua própria instância; por exemplo, https://cryptic-headland-94862.herokuapp.com/https://example.com .
Portanto, se você tentar usar https://cors-anywhere.herokuapp.com, descobrir que está em baixo (o que às vezes acontece), considere obter uma conta Heroku (se ainda não o fez) e faça 2 ou 3 minutos para executar as etapas acima para implantar seu próprio servidor CORS Anywhere no Heroku.
Independentemente de você executar ou usar https://cors-anywhere.herokuapp.com ou outro proxy aberto, esta solução funcionará mesmo se a solicitação for aquela que aciona os navegadores para fazer uma OPTIONS
solicitação de comprovação CORS - porque, nesse caso, o O proxy também envia de volta os cabeçalhos Access-Control-Allow-Headers
e Access-Control-Allow-Methods
necessários para tornar o preflight bem-sucedido.
Como evitar o preflight do CORS
O código na pergunta aciona um preflight do CORS, pois envia um Authorization
cabeçalho.
https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS#Preflighted_requests
Mesmo sem isso, o Content-Type: application/json
cabeçalho também acionaria o preflight.
O que “comprovar” significa: antes que o navegador tente digitar o POST
código da pergunta, ele primeiro envia uma OPTIONS
solicitação ao servidor - para determinar se o servidor está optando por receber uma origem cruzada POST
que inclua os cabeçalhos Authorization
e Content-Type: application/json
.
Funciona muito bem com um pequeno script curl - eu recebo meus dados.
Para testar corretamente curl
, você deve emular a OPTIONS
solicitação de comprovação que o navegador envia:
curl -i -X OPTIONS -H "Origin: http://127.0.0.1:3000" \
-H 'Access-Control-Request-Method: POST' \
-H 'Access-Control-Request-Headers: Content-Type, Authorization' \
"https://the.sign_in.url"
... https://the.sign_in.url
substituído por qualquer que seja o seu sign_in
URL real .
A resposta que o navegador precisa receber dessa OPTIONS
solicitação deve incluir cabeçalhos como este:
Access-Control-Allow-Origin: http://127.0.0.1:3000
Access-Control-Allow-Methods: POST
Access-Control-Allow-Headers: Content-Type, Authorization
Se a OPTIONS
resposta não incluir esses cabeçalhos, o navegador será interrompido e nunca tentará enviar a POST
solicitação. Além disso, o código de status HTTP para a resposta deve ser 2xx - normalmente 200 ou 204. Se houver outro código de status, o navegador irá parar ali.
O servidor na pergunta está respondendo à OPTIONS
solicitação com um código de status 501, o que aparentemente significa que está tentando indicar que não implementa suporte para OPTIONS
solicitações. Outros servidores normalmente respondem com um código de status 405 "Método não permitido" neste caso.
Portanto, você nunca poderá fazer POST
solicitações diretamente a esse servidor a partir do seu código JavaScript de front-end se o servidor responder a essa OPTIONS
solicitação com um 405 ou 501 ou qualquer coisa que não seja um 200 ou 204 ou se não responder com os necessários cabeçalhos de resposta.
A maneira de evitar o desencadeamento de um preflight para o caso na pergunta seria:
- se o servidor não exigir um
Authorization
cabeçalho de solicitação, mas (por exemplo) se basear nos dados de autenticação incorporados no corpo da POST
solicitação ou como um parâmetro de consulta
- se o servidor não exigiu que o
POST
corpo tivesse um Content-Type: application/json
tipo de mídia, mas o aceitou POST
como application/x-www-form-urlencoded
com um parâmetro chamado json
(ou qualquer outro) cujo valor são os dados JSON
Como corrigir os problemas do cabeçalho "Acesso-controle-permissão-origem" não deve ser o curinga
Estou recebendo outra mensagem de erro:
O valor do cabeçalho 'Access-Control-Allow-Origin' na resposta não deve ser o curinga '*' quando o modo de credenciais da solicitação for 'include'. Portanto, a origem ' http://127.0.0.1:3000 ' não é permitida. O modo de credenciais de solicitações iniciadas pelo XMLHttpRequest é controlado pelo atributo withCredentials.
Para uma solicitação que inclui credenciais, os navegadores não permitirão que o código JavaScript do front-end acesse a resposta se o valor do Access-Control-Allow-Origin
cabeçalho da resposta for *
. Em vez disso, o valor nesse caso deve corresponder exatamente à origem do seu código de front-end http://127.0.0.1:3000
,.
Consulte Solicitações credenciadas e curingas no artigo MDN HTTP access control (CORS).
Se você controla o servidor para o qual está enviando a solicitação, uma maneira comum de lidar com esse caso é configurar o servidor para pegar o valor do Origin
cabeçalho da solicitação e repetir / refletir isso no valor do Access-Control-Allow-Origin
cabeçalho da resposta. Por exemplo, com nginx:
add_header Access-Control-Allow-Origin $http_origin
Mas esse é apenas um exemplo; outros sistemas de servidor (web) fornecem maneiras semelhantes de ecoar valores de origem.
Estou usando o Chrome. Eu também tentei usar o Chrome CORS Plugin
Esse plug-in do Chrome CORS aparentemente injeta simplesmente um Access-Control-Allow-Origin: *
cabeçalho na resposta que o navegador vê. Se o plug-in fosse mais inteligente, o que estaria fazendo seria definir o valor desse Access-Control-Allow-Origin
cabeçalho de resposta falsa para a origem real do seu código JavaScript de front-end http://127.0.0.1:3000
,.
Portanto, evite usar esse plug-in, mesmo para testes. É apenas uma distração. Se você deseja testar quais respostas você obtém do servidor sem que o navegador as filtre, é melhor usá-lo curl -H
como acima.
Quanto ao código JavaScript de front-end para a fetch(…)
solicitação na pergunta:
headers.append('Access-Control-Allow-Origin', 'http://localhost:3000');
headers.append('Access-Control-Allow-Credentials', 'true');
Remova essas linhas. Os Access-Control-Allow-*
cabeçalhos são cabeçalhos de resposta . Você nunca deseja enviá-los em uma solicitação. O único efeito que isso terá é acionar um navegador para realizar um preflight.
Content-Type
eAccess-Control-Allow-Origin
- obrigado!open /Applications/Google\ Chrome.app --args --disable-web-security --user-data-dir
Este erro ocorre quando o URL do cliente e o servidor não correspondem, incluindo o número da porta. Nesse caso, você precisa habilitar seu serviço para o CORS, que é o compartilhamento de recursos de origem cruzada.
Se você estiver hospedando um serviço Spring REST, poderá encontrá-lo no suporte ao CORS da postagem do blog no Spring Framework .
Se você estiver hospedando um serviço usando um servidor Node.js.,
npm install cors --save
Adicione as seguintes linhas ao seu server.js
fonte
including the port number
:(O problema surgiu porque você adicionou o seguinte código como cabeçalho de solicitação no seu front-end:
Esses cabeçalhos pertencem à resposta , não à solicitação. Portanto, remova- os, incluindo a linha:
Sua solicitação tinha 'Content-Type: application / json', portanto, acionou o que é chamado de comprovação CORS. Isso fez com que o navegador enviasse a solicitação com o método OPTIONS. Consulte CORS preflight para obter informações detalhadas.
Portanto, em seu back-end , você deve lidar com essa solicitação pré-comprovada retornando os cabeçalhos de resposta que incluem:
Obviamente, a sintaxe real depende da linguagem de programação usada para seu back-end.
No seu front-end, deve ser assim:
fonte
No meu caso, eu uso a solução abaixo
Front-end ou Angular
back-end (eu uso php)
fonte
Apenas meus dois centavos ... sobre como usar um proxy CORS para contornar "Não
Access-Control-Allow-Origin
cabeçalho"Para aqueles que trabalham com php no back-end, implantar um "proxy CORS" é tão simples quanto:
crie um arquivo chamado 'no-cors.php' com o seguinte conteúdo:
$URL = $_GET['url']; echo json_encode(file_get_contents($URL)); die();
no seu front end, faça algo como:
fetch('https://example.com/no-cors.php' + '?url=' + url) .then(response=>{*/Handle Response/*})
fonte
Tire isto:
fonte
Usando
dataType: 'jsonp'
funcionou para mim.fonte
No meu caso, o servidor da web impediu o método "OPTIONS"
Verifique seu servidor da web para o método de opções
mudar para
fonte
Eu estava trabalhando com o Spring REST e resolvi adicionando os AllowedMethods ao WebMvcConfigurer.
fonte
Eu estava recebendo esse erro no meu local. Executei o Visual Studio como administrador e ele foi resolvido.
fonte