Hoje temos uma rápida, porém essencial dica: Por que um app não carrega dados externos? Como resolver o Cross Origin Resource Sharing (CORS) policy error?
Se você, meu amigo, minha amiga, desenvolvedor já precisou consumir dados estando fora do servidor (Por exemplo, consumir uma API REST que sirva o conteúdo em JSON à partir de uma aplicação com AngularJS ou Ionic Framework), então é provável que tenha se deparado com erro do CORS.
Ao fazer o deploy do webservice para um servidor remoto (de desenvolvimento ou produção), o frontend misteriosamente pára de funcionar.
Todas aquelas lindas requisições XHR abstraídas em $.ajax, ou nos $http e $resource da vida, ou qualquer outra forma de pegar os dados da sua API páram de funcionar quando os rescursos do servidor e o front já não estão na mesma oirigin
CORS
Pra resolver, comece identificando a causa
Primeiro, temos de entender o que significa CORS. Cross Origin Resource Sharing é o quando precisamos interagir com recursos fora do servidor. Por medidas de segurança, navegadores desktop , e algumas versões de sistemas operacionais Android e iOS exigem que seja declarado no servidor de origem os clients autorizados a consumir os dados.
Vou comentar agora duas formas difernetes, sendo uma para desenvolvimento, e outra mais adequada para produção.
Quebrando um galho:
Enganando seu navegador para burlar CORS. (Bypassing CORS)
Bom, como para permitir a conexão em diferentes origens é necessário apenas um Header autorizando isso explicitamente, existe uma forma bem simples à lá gambiarration, que é interceptar as requisições antes do navegador, inserindo o Header permissivo nelas.
Isso pode ser feito para Google Chrome, com Esta extensão maneira
Interceptando com um proxy
Você pode criar um proxy para enviar o header. Sorte que sua que o camarada @suissa já fez isso pra vc:
http://cors-server.getup.io/url/:SUAURLPARACORS permite que vc insira :SUAURLPARACORS alí na url e tenha o header adicionado à sua requisição.
NÃO OBSTANTE QUEBRAR O SEU GALHO, ainda tá OpenSource este pequeno server: https://github.com/suissa/cors-server
O jeito certo
declarando no servidor os clients autorizados à consumir os dados
O erro de segurança do CORS é justamente por que o navegador quer, antes de consumir os dados, ter certeza que o servidor está ciente que ele está fazendo isso.
É necessário declarar no header
Access-Control-Allow-Origin
do server os clients que tem permissão para consumir os dados
Definimos as origins permitidas com seu hostname, ou wildcards, por exemplo:
localhost
192.189.200.**
Para um wildcard geral e genérico (não muito indicado), usamos *
. Veja algumas formas de definir este cabeçalho:
No Apache Web Server
Usando headers para evitar problemas com CORS
No servidor Apache podemos usar um arquivo .htaccess
com o seguinte conteúdo:
1 | Header set Access-Control-Allow-Origin "*" |
Com nGinx Server
setando header server-wide no nGinx
No nginX (o servidor que vc precisa conhecer, se ainda não conhece), a configuração site-wide pode ser feita diretamente no arquivo .vhost.
1 | location / { |
Com PHP
setando headers diretamente com PHP, para evitar problemas de CORS
Caso as configurações de segurança do seu servidor permitam, é possível fazer pelo PHP, mesmo sem acesso ao .htacces.
Lembrando que definir os header via php deve ser sempre feito em uma vez só, preferencialmente em um mesmo arquivo, para evitar erros de header already sent
.
1 |
|
Com NodeJS (Express.js)
setando headers com NodeJS, para que a API sirva o cabeçalho necessário
Basta criar um middleware que adicione à response o header. Isso é feito com res.header()
.
1 | app.use(function(req, res, next) { |
Para ASP.net
*se vc usa asp.net, pode fazer assim para definir os headers do seu servidor**
Se não tiver acesso às configurações do ISS, pode tentar definir o header diretamente no seu código:1
Response.AppendHeader("Access-Control-Allow-Origin", "*");
Outras opções para resolver problema de CORS, server side:
Para ver uma boa lista com dicas de como configurar os Headers necessários para seu servidor servir o conteúdo sem esbarrar no CORS Policy error, dê uma conferida no http://enable-cors.org
##Para Phonegap/Cordova/Ionic Framework:
Declarando no Config.XML da sua aplicação PhoneGap/Cordova/Ionic as Origins permitidas.
Para versões mais recentes do Android (à partir do kitkat, eu acho :P ), trounou-se necessário declarar permissão de acesso à recursos externos no arquivo config.xml.
Antes isso não era obrigatório, então era possível usar o tweak da extensão do Chrome durante o desenvolvimento, e depois apenas empacotar seu .apk que tudo ficaria bem.
Hoje, basta instalar o plugin Corvoda Plugin WhiteList via terminal:
1 | (Cordova) |
E, uma vez instalado, declarar no arquivo CONFIG.XML do projeto as origens permitidas.
São 2 parâmetros: access origin
e allow-navigation
. O Access origin permite interação com a url ou domínio, ou wildcard inserido. O Allow-navigation especifica quais domínios ou sites/wildcard podem ser abertos por um link da sua aplicação.
1 | <access origin="*://*.urldaSuaAPI.com/*"/> |
Além da declaração do
header
no server-side, declararaccess origin
no CONFIG.XML do seu APP pode ser necessário
Resumindo e Concluindo os paranauê
Então é o seguinte: CORS é o nome da requisição feita de locais/servidores diferentes. Quando vc está local e baixa dados do localhost, não há Cors. Pois não fere a same origin policy
, dos navegadores.
Quando é feita uma requisição externa, o servidor deve declarar permissão para a origem, ou wildcard, permitindo o acesso.
Caso isso não seja possível em uma das 20 formas diferentes em linguagens diferentes e ambientes distintos, vc pode sempre usar uma extensão que intercepte suas requisições e adicione o Access-Control-Allow-Origin
à elas.
Comments