Comment activer CORS en AngularJs

j'ai créé une démo en utilisant JavaScript pour Flickr Photo search API. Maintenant je le convertis en AngularJs. J'ai cherché sur internet et j'ai trouvé la configuration ci-dessous.

Configuration:

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

Service:

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'}
         });
     }
});

contrôleur:

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

mais j'ai quand même eu la même erreur. Voici quelques liens que j'ai essayé:

XMLHttpRequest ne peut pas load URL. Origine non autorisée par contrôle D'accès-autorisation-origine

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

EDIT:

j'ai créé un serveur proxy dans node.js sur suggestion 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);

Final Edition

j'ai enlevé l'en-tête d'Autorisation

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

et il tourne bien. J'ai obtenu ce que je voulais. Merci à tous d'avoir participé à cette question

124
demandé sur Community 2014-05-23 11:05:39

6 réponses

, Non. Le serveur auquel vous faites la demande doit mettre en œuvre CORS pour accorder JavaScript à partir de l'accès à votre site web. Votre JavaScript ne peut pas se donner la permission d'accéder à un autre site web.

168
répondu Quentin 2014-05-23 08:10:55

j'ai eu un problème similaire et pour moi il s'est réduit à ajouter les en-têtes HTTP suivants au réponse du fin de réception :

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

vous pouvez préférer ne pas utiliser le * à la fin, mais seulement le nom de domaine de l'hôte qui envoie les données. Comme *.example.com

mais cela n'est réalisable que lorsque vous avez accès à la configuration du serveur.

59
répondu Erwin 2014-05-23 10:17:29

Essayez d'utiliser le service de ressources à consommer de flickr jsonp:

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' });
});

modèle:

<div class="masonry: 240;" ng-controller="MasonryCtrl">
    <div class="masonry-item" ng-repeat="item in photos.items">
        <img ng-src="{{ item.media.m }}" />
    </div>
</div>
9
répondu XGreen 2014-05-23 08:51:00

cette question se pose en raison de la Politique de modèle de sécurité de l'application web qui est même Politique D'origine en vertu de la Politique, un navigateur Web permet des scripts contenus dans une première page Web d'accéder aux données dans une deuxième page Web, mais seulement si les deux pages web ont la même origine. Cela signifie que le demandeur doit correspondre à l'hôte exact, le protocole et le port du site demandeur.

nous avons plusieurs options pour surmonter ce problème D'en-tête CORS.

  1. en utilisant le Proxy - dans cette solution, nous exécuterons un proxy tel que lorsque la requête passe par le proxy, il apparaîtra comme s'il s'agissait d'une même origine. Si vous utilisez le nodeJS vous pouvez utiliser cors-anywhere pour faire les trucs proxy. https://www.npmjs.com/package/cors-anywhere .

    exemple : -

    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 est une méthode pour envoyer des données JSON sans se soucier des questions transversales.Il n'utilise pas L'objet XMLHttpRequest.Il utilise l'étiquette <script> à la place. https://www.w3schools.com/js/js_json_jsonp.asp

  3. Côté Serveur - côté serveur nous devons activer les requêtes d'origine croisée. Tout d'abord nous allons obtenir le Contrôlé demandes (OPTIONS) et nous avons besoin pour permettre à la requête qui est le code d'état 200 (ok).

    requests Préflighted envoie d'abord un en-tête de requête D'OPTIONS HTTP à la ressource sur l'autre domaine, afin de déterminer si la requête actuelle peut être envoyée en toute sécurité. Les requêtes intersites sont préfixées comme ceci puisqu'elles peuvent avoir des implications pour les données des utilisateurs. En particulier, une requête est pré-allumée si elle utilise des méthodes autres que GET ou POST. Aussi, si POST est utilisé pour envoyer des données de requête avec un type de contenu autre que application/x-www-form-urlencoded, multipart/form-data, ou text/plain, par exemple si la requête POST envoie une charge utile XML au serveur en utilisant application/xml ou text/xml, alors la requête est pré-allumée. Il définit des en-têtes personnalisés dans la requête (par exemple, la requête utilise un en-tête tel que X-PINGOTHER)

    si vous utilisez le spring simplement en ajoutant le code ci-dessous résoudra le problème. Ici, j'ai désactivé le jeton csrf qui n'a pas d'importance activer/désactiver selon vos besoins.

    @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("*");
                }
            };
        }
    }
    

    si vous utilisez le code de sécurité de ressort ci-dessous avec le code ci-dessus.

    @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();
        }
    
    }
    
2
répondu Niru 2018-08-23 13:21:33

a répondu par moi-même.

de la SCRO angular js + restEasy sur le POST

enfin je suis venu à ce contournement: La raison pour laquelle il a fonctionné avec IE est parce que IE envoie directement un poste au lieu de la première une demande avant le vol pour demander la permission. Mais je ne sais toujours pas pourquoi le filtre n'a pas été en mesure de gérer une requête D'OPTIONS et envoie par défaut des en-têtes qui ne sont pas décrits dans le filtre (semble comme un override pour cela seulement cas. .. peut-être un restEasy chose ...)

J'ai donc créé un chemin D'OPTIONS dans mon service rest qui réécrit la réponse et inclut les en-têtes dans la réponse en utilisant l'en-tête de réponse

je suis toujours à la recherche de la façon propre de le faire si quelqu'un a fait face à cela avant.

1
répondu J.Doe 2017-05-23 11:33:26
        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);
-1
répondu shiva samalla 2018-02-12 11:28:29