Como ativar CORS em AngularJs

Eu criei uma demonstração usando JavaScript para a API de pesquisa de fotos do Flickr. Agora estou convertendo para o AngularJs. Eu procurei na internet e encontrei abaixo configuração.

Configuração:

myApp.config(function($httpProvider) { $httpProvider.defaults.useXDomain = true; delete $httpProvider.defaults.headers.common['X-Requested-With']; }); 

Serviço:

 myApp.service('dataService', function($http) { delete $http.defaults.headers.common['X-Requested-With']; this.flickrPhotoSearch = function() { return $http({ method: 'GET', url: 'http://api.flickr.com/services/rest/?method=flickr.photos.search&api_key=3f807259749363aaa29c76012fa93945&tags=india&format=json&callback=?', dataType: 'jsonp', headers: {'Authorization': 'Token token=xxxxYYYYZzzz'} }); } }); 

Controlador:

 myApp.controller('flickrController', function($scope, dataService) { $scope.data = null; dataService.flickrPhotoSearch().then(function(dataResponse) { $scope.data = dataResponse; console.log($scope.data); }); }); 

Mas ainda tenho o mesmo erro. Aqui estão alguns links que eu tentei:

XMLHttpRequest não pode carregar o URL. Origem não permitida pelo Access-Control-Allow-Origin

http://samurails.com/tutorial/cors-with-angular-js-and-sinatra/

EDITAR:

Eu criei um servidor proxy em node.js por sugestão de @Quentin:

 var http = require('http'); var url = require('url'); var fs = require('fs'); var server; server = http.createServer(function (req, res) { // your normal server code var path = url.parse(req.url).pathname; fs.readFile(__dirname + path, function (err, data) { if (err) { return send404(res); } res.writeHead(200, {'Content-Type':path == 'json.js' ? 'text/javascript' : 'text/html'}); res.write(data, 'utf8'); res.end(); }); }), server.listen(8001); //using express to load customizes static files var express = require("express"), app = express(); app.all("/api/*", function (req, res, next) { res.header("Access-Control-Allow-Origin", "*"); res.header("Access-Control-Allow-Headers", "Cache-Control, Pragma, Origin, Authorization, Content-Type, X-Requested-With"); res.header("Access-Control-Allow-Methods", "GET, PUT, POST"); return next(); }); app.use("/js", express.static(__dirname + '/js')); app.listen(3001); 

Edição final

Eu removi o header de autorização

headers: {'Authorization': 'Token token=xxxxYYYYZzzz'}

e está correndo bem. Eu tenho o que eu queria. Obrigado a todos pela participação nesta questão

Você não O servidor para o qual você está fazendo a solicitação precisa implementar o CORS para conceder JavaScript a partir do access ao seu site. Seu JavaScript não pode conceder permissão para acessar outro site.

Eu tive um problema semelhante e, para mim, resumiu-se a adicionar os seguintes headers HTTP na resposta da extremidade de recebimento :

 Access-Control-Allow-Headers: Content-Type Access-Control-Allow-Methods: GET, POST, OPTIONS Access-Control-Allow-Origin: * 

Você pode preferir não usar o * no final, mas apenas o nome de domínio do host que envia os dados. Como *.example.com

Mas isso só é viável quando você tem access à configuração do servidor.

Tente usar o serviço de resources para consumir o jsonp do flickr:

 var MyApp = angular.module('MyApp', ['ng', 'ngResource']); MyApp.factory('flickrPhotos', function ($resource) { return $resource('http://api.flickr.com/services/feeds/photos_public.gne', { format: 'json', jsoncallback: 'JSON_CALLBACK' }, { 'load': { 'method': 'JSONP' } }); }); MyApp.directive('masonry', function ($parse) { return { restrict: 'AC', link: function (scope, elem, attrs) { elem.masonry({ itemSelector: '.masonry-item', columnWidth: $parse(attrs.masonry)(scope) }); } }; }); MyApp.directive('masonryItem', function () { return { restrict: 'AC', link: function (scope, elem, attrs) { elem.imagesLoaded(function () { elem.parents('.masonry').masonry('reload'); }); } }; }); MyApp.controller('MasonryCtrl', function ($scope, flickrPhotos) { $scope.photos = flickrPhotos.load({ tags: 'dogs' }); }); 

Modelo:

 

Esse problema ocorre devido à política de modelo de segurança de aplicativo Web que é a mesma política de origem. Na diretiva, um navegador da Web permite que scripts contidos em uma primeira página da Web acessem dados em uma segunda página da Web, mas somente se ambas as páginas tiverem a mesma origem. Isso significa que o solicitante deve corresponder ao host, protocolo e porta exatos do site solicitante.

Temos várias opções para superar esse problema de header do CORS.

  1. Usando Proxy – Nesta solução, executaremos um proxy de forma que, quando o pedido passar pelo proxy, ele apareça como se fosse da mesma origem. Se você estiver usando o nodeJS, você pode usar cors-anywhere para fazer o proxy. https://www.npmjs.com/package/cors-anywhere .

    Exemplo : –

     var host = process.env.HOST || '0.0.0.0'; var port = process.env.PORT || 8080; var cors_proxy = require('cors-anywhere'); cors_proxy.createServer({ originWhitelist: [], // Allow all origins requireHeader: ['origin', 'x-requested-with'], removeHeaders: ['cookie', 'cookie2'] }).listen(port, host, function() { console.log('Running CORS Anywhere on ' + host + ':' + port); }); 
  2. JSONP – JSONP é um método para enviar dados JSON sem se preocupar com problemas entre domínios. Ele não usa o object XMLHttpRequest. Ele usa a tag . https://www.w3schools.com/js/js_json_jsonp.asp

  3. Lado do servidor - No lado do servidor, precisamos ativar as solicitações de origem cruzada. Primeiro, obteremos as solicitações de Preflight (OPTIONS) e precisamos permitir a solicitação que é o código de status 200 (ok).

    Solicitações preflighted primeiro enviam um header de solicitação HTTP OPTIONS para o recurso no outro domínio, a fim de determinar se a solicitação real é segura para enviar. As solicitações entre sites são pré-formatadas assim, pois podem ter implicações nos dados do usuário. Em particular, uma solicitação é pré-determinada se usar methods diferentes de GET ou POST. Além disso, se o POST for usado para enviar dados de solicitação com um tipo de conteúdo diferente de application / x-www-form-urlencoded, multipart / form-data ou text / plain, por exemplo, se a solicitação POST enviar uma carga XML ao servidor usando application / xml ou text / xml, a solicitação é preflighted. Ele define headers personalizados na solicitação (por exemplo, a solicitação usa um header como X-PINGOTHER)

    Se você estiver usando a primavera, basta adicionar o código abaixo para resolver o problema. Aqui eu desativei o token csrf que não importa ativar / desativar de acordo com sua necessidade.

     @SpringBootApplication public class SupplierServicesApplication { public static void main(String[] args) { SpringApplication.run(SupplierServicesApplication.class, args); } @Bean public WebMvcConfigurer corsConfigurer() { return new WebMvcConfigurerAdapter() { @Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping("/**").allowedOrigins("*"); } }; } } 

    Se você estiver usando o código de segurança de mola abaixo, juntamente com o código acima.

     @Configuration @EnableWebSecurity public class SupplierSecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { http.csrf().disable().authorizeRequests().antMatchers(HttpMethod.OPTIONS, "/**").permitAll().antMatchers("/**").authenticated().and() .httpBasic(); } } 

Respondido por mim mesmo.

CORS angular js + restEasy no POST

Bem, finalmente cheguei a esta solução alternativa: A razão que funcionou com o IE é porque o IE envia diretamente um POST em vez de primeiro uma solicitação de comprovação para pedir permissão. Mas eu ainda não sei por que o filtro não foi capaz de gerenciar uma solicitação OPTIONS e envia por padrão headers que não são descritos no filtro (parece uma substituição para aquele único caso … talvez uma coisa de descanso … .)

Então eu criei um caminho OPTIONS no meu serviço de descanso que reescreve a resposta e inclui os headers na resposta usando o header de resposta

Eu ainda estou procurando a maneira limpa de fazê-lo se alguém enfrentou isso antes.

  var result=[]; var app = angular.module('app', []); app.controller('myCtrl', function ($scope, $http) { var url="";// your request url var request={};// your request parameters var headers = { // 'Authorization': 'Basic ' + btoa(username + ":" + password), 'Access-Control-Allow-Origin': true, 'Content-Type': 'application/json; charset=utf-8', "X-Requested-With": "XMLHttpRequest" } $http.post(url, request, { headers }) .then(function Success(response) { result.push(response.data); $scope.Data = result; }, function Error(response) { result.push(response.data); $scope.Data = result; console.log(response.statusText + " " + response.status) }); }); And also add following code in your WebApiConfig file var cors = new EnableCorsAttribute("*", "*", "*"); config.EnableCors(cors);