Artigo original: https://www.freecodecamp.org/news/access-control-allow-origin-header-explained/
Frequentemente, ao chamarmos uma API, vemos um erro no console com essa aparência:
Access to fetch at 'http://um_site_qualquer.com' from origin 'http://seu_site.com' has been blocked by CORS policy: The 'Access-Control-Allow-Origin' header has a value that is not equal to the supplied origin
Neste artigo, aprenderemos o motivo de esse erro aparecer e como resolvê-lo.
O que é o cabeçalho Access-Control-Allow-Origin
?
Access-Control-Allow-Origin
é um cabeçalho de CORS. CORS, ou Cross Origin Resource Sharing (em português, "compartilhamento de recursos de origens diferentes"), é um mecanismo que os navegadores têm para permitir que um site em execução no ponto de origem A solicite recursos no ponto de origem B.
"Origin", ou origem, neste caso, não é apenas um nome de host, mas uma combinação da porta, do nome do host e do esquema, por exemplo: http://meu_site.exemplo.com:8080/
Aqui temos um exemplo do que acontece -
- Tenho um ponto de origem A:
http://meu_site.com
e quero obter recursos do ponto de origem B:http://seu_site.com
. - Para proteger a sua segurança, o navegador não me permitirá acessar recursos de seu_site.com e bloqueará minha solicitação.
- Para permitir que o ponto de origem A acesse seus recursos, o ponto de origem B precisará permitir que o navegador saiba que não há problema em me permitir obter recursos de seu ponto de origem.
Aqui temos um exemplo da Mozilla Developer Network que explica bem o caso:
Com a ajuda do CORS, os navegadores permitem que os pontos de origem compartilhem recursos entre eles.
Existem alguns cabeçalhos (texto em inglês) que permitem o compartilhamento de recursos entre pontos de origem, mas o principal deles é Access-Control-Allow-Origin
. Ele informa o navegador quais origens têm a permissão de receber solicitações nesse servidor.
Quem precisa definir Access-Control-Allow-Origin
?
Para entender quem precisa definir esse cabeçalho, pense no seguinte cenário: você está navegando por um site da web que é usado para visualizar e ouvir música. O site tenta fazer uma conexão com seu banco em segundo plano de modo inadequado.
Quem deve ter, ao final de contas, a capacidade de evitar que esse site da web malicioso roube dados do banco? O banco! Assim, é o banco que precisará proteger seus recursos, definindo o cabeçalho Access-Control-Allow-Origin
como parte da resposta.
Lembre-se: o ponto de origem responsável por servir os recursos é quem precisa definir esse cabeçalho.
Como usar e quando passar esse cabeçalho
Aqui temos um exemplo dos valores que você pode definir:
Access-Control-Allow-Origin : *
: permite qualquer origem.Access-Control-Allow-Origin : http://mysite.com
: permite solicitações apenas de meu_site.com.
Vejamos isso em funcionamento
Vamos ver um exemplo. Você pode conferir esse código no meu repositório no GitHub.
Criaremos um servidor no ponto de origem A http://localhost:8000
, que enviará a Hello
a um endpoint da api
. Chamaremos esse endpoint criando um client no ponto de origem B http://localhost:3000
e usaremos a api fetch para solicitar o recurso. Esperamos ver a string Hello
ser passada pelo ponto de origem A ao console do navegador do ponto de origem B.
Vamos supor que nós temos um ponto de origem em funcionamento em http://localhost:8000
que serve esse recurso no endpoint /api
. O servidor envia uma resposta com o cabeçalho Access-Control-Allow-Origin
.
const express = require("express");
const app = express();
const port = process.env.SERVER_PORT || 8000;
// Adicionar os cabeçalhos Access-Control-Allow-Origin
app.use((req, res, next) => {
res.setHeader("Access-Control-Allow-Origin", "https://seu_site.com");
res.header(
"Access-Control-Allow-Headers",
"Origin, X-Requested-With, Content-Type, Accept"
);
next();
});
app.get("/api", (req, res) => {
res.json("Hello");
});
app.listen(port, () => console.log(`Listening on port ${port}`));
No lado do client, você pode chamar esse endpoint através de fetch
, assim:
fetch('http://localhost:8000/api')
.then(res => res.json())
.then(res => console.log(res));
Agora, abra o console do navegador para ver o resultado.
Como o cabeçalho, de momento, está definido para aceitar acessos apenas de https://seu_site.com
, o navegador bloqueará o acesso ao recurso e você verá um erro no console.
Agora, para consertarmos isso, altere os cabeçalhos para:
res.setHeader("Access-Control-Allow-Origin", "*");
Confira o console do navegador e agora você verá a string Hello
.