Tentando usar o fetch e passar em modo: no-cors
Eu posso atingir este endpoint, http://catfacts-api.appspot.com/api/facts?number=99
via Postman e ele retorna JSON
.
Além disso, estou usando o create-react-app e gostaria de evitar a configuração de qualquer configuração de servidor.
No código do meu cliente eu estou tentando usar 'fetch' para fazer a mesma coisa, mas eu recebo o erro:
Não ' Access-Control-Allow-Origin' o cabeçalho está presente no recurso. Origem 'http://localhost:3000' portanto, não é permitido acesso. Se uma resposta opaca serve as suas necessidades, defina o pedido's mode to 'nocors' para ir buscar o recurso com CORS desabilitado.
Então estou tentando passar em um objeto, para o meu Fetch que vai desabilitar CORS, assim:
fetch('http://catfacts-api.appspot.com/api/facts?number=99', { mode: 'no-cors'})
.then(blob => blob.json())
.then(data => {
console.table(data);
return data;
})
.catch(e => {
console.log(e);
return e;
});
Curiosamente, o erro que recebo é na verdade um erro de sintaxe com esta função. Não tenho certeza se o meu fetch
real está quebrado, porque quando eu removo o objeto { mode: 'no-cors' }, e o forneço com um URL diferente, ele funciona muito bem.
Eu também tentei passar no objeto { mode: 'opaque'}
, mas isto retorna o erro original de cima.
Acredito que tudo o que preciso de fazer é desactivar o CORS... O que estou a perder?
Adicionar
mode: 'no-cors'
não vai fazer as coisas funcionarem magicamente. Na verdade, isso torna as coisas piores, porque um efeito que tem é dizer aos navegadores, "Bloqueie meu código frontend JavaScript de olhar para o conteúdo do corpo de resposta e cabeçalhos em todas as circunstâncias". O que acontece com os pedidos de origem cruzada do frontend JavaScript é que os navegadores por padrão bloqueiam o código do frontend de acesso aos recursos de origem cruzada. Se um site enviaAccess-Control-Allow-Origin
em suas respostas, então os navegadores irão relaxar esse bloqueio e permitir que seu código acesse a resposta. Mas se um site não enviar um cabeçalho "Acess-Control-Allow-Origin" em suas respostas, não há como o seu código front-end acessar diretamente as respostas desse site. Em particular, você não pode corrigir isso especificandomode: 'no-cors'
(de fato isso segura* que seu código frontend não possa acessar o conteúdo da resposta). No entanto, uma coisa que virá funcionar é se você enviar seu pedido através de [um proxy CORS][1], desta forma:**Note: se quando você for tentar usar https://cors-anywhere.herokuapp.com, você descobre que está em baixo***, você também pode facilmente implantar seu próprio proxy para Heroku em literalmente apenas 2-3 minutos, com 5 comandos:
Depois de executar esses comandos, você vai acabar com seu próprio servidor CORS Anywhere rodando em, por exemplo, https://cryptic-headland-94862.herokuapp.com/. Então, ao invés de prefixar a URL do seu pedido com `https://cors-anywhere.herokuapp.com', prefira-a com a URL da sua própria instância; por exemplo, https://cryptic-headland-94862.herokuapp.com/https://example.com.
A solução para mim era apenas fazê-lo do lado do servidor.
Eu utilizei a biblioteca C#
WebClient
para obter os dados (no meu caso eram dados de imagem) e enviá-los de volta para o cliente. Lá's provavelmente algo muito similar no seu idioma escolhido do lado do servidor.Pode ajustá-lo ao seu próprio caso de uso. O ponto principal é
client.DownloadData()
trabalhou sem nenhum erro CORS. Tipicamente os problemas CORS são apenas entre websites, por isso não há problema em fazer 'cross-site' pedidos do seu servidor.Então a chamada para o React fetch é tão simples como:
Solução muito fácil (2 min para configurar) é utilizar o pacote local-ssl-proxy do
npm
.O uso é muito directo:
1. instale o pacote:
npm install -g local-ssl-proxy
2. Enquanto executa o seu
local-server
mascare-o com olocal-ssl-proxy --source 9001 --target 9000
P.S: Substitua
--target 9000' pelo
-- "número da sua porta"e
--source 9001' por--source "número da sua porta +1"