web-dev-qa-db-de.com

So aktivieren Sie CORS in AngularJs

Ich habe eine Demo mit JavaScript für die Flickr-Fotosuch-API erstellt. Jetzt konvertiere ich es in die AngularJs . Ich habe im Internet gesucht und unten Konfiguration gefunden. 

Aufbau:

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

Bedienung:

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

Regler:

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

Aber ich habe immer noch den gleichen Fehler ... Hier sind einige Links, die ich ausprobiert habe:

XMLHttpRequest kann URL nicht laden. Ursprung nicht zulässig für Zugriffskontrolle - Herkunft zulassen

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

EDIT:

Ich habe einen Proxy-Server in node.js auf Vorschlag von @Quentin erstellt:

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 Edit

Ich habe den Autorisierungsheader entfernt

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

und es läuft gut. Ich habe das bekommen, was ich wollte ... Danke für die Teilnahme an dieser Frage

133
ankitr

Du nicht Der Server, an den Sie die Anforderung stellen, muss CORS implementieren, um JavaScript von Ihrer Website aus zuzulassen. Ihr JavaScript kann sich nicht erlauben, auf eine andere Website zuzugreifen.

173
Quentin

Ich hatte ein ähnliches Problem und für mich ging es darum, die folgenden HTTP-Header an der Antwort des Empfangsendes hinzuzufügen:

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

Möglicherweise möchten Sie den * am Ende nicht verwenden, sondern nur den Domänennamen des Hosts, der die Daten sendet. Wie *.example.com

Dies ist jedoch nur möglich, wenn Sie auf die Konfiguration des Servers zugreifen können.

61
Erwin

Verwenden Sie den Ressourcendienst, um flickr jsonp zu verbrauchen:

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

Vorlage:

<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
Ali Habibzadeh

Dieses Problem tritt aufgrund einer Sicherheitsmodellrichtlinie für Webanwendungen auf, bei der es sich um die gleiche Ursprungsrichtlinie handelt . Unter der Richtlinie lässt ein Webbrowser den Zugriff auf Skripts zu, die auf einer ersten Webseite enthalten sind Daten in einer zweiten Webseite, jedoch nur, wenn beide Webseiten denselben Ursprung haben. Dies bedeutet, dass der Anforderer mit dem genauen Host, Protokoll und Port der anfordernden Site übereinstimmen muss.

Wir haben mehrere Möglichkeiten, um dieses CORS-Header-Problem zu lösen.

  1. Verwenden von Proxy - In dieser Lösung wird ein Proxy ausgeführt, sodass beim Durchlaufen des Proxys eine Anfrage so aussieht, als ob es sich um denselben Ursprung handelt. Wenn Sie den nodeJS verwenden, können Sie cors-anywhere verwenden das Proxy-Zeug. https://www.npmjs.com/package/cors-anywhere .

    Beispiel : -

    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 ist eine Methode zum Senden von JSON-Daten, ohne sich um domänenübergreifende Probleme zu kümmern. Wird nicht verwendet das XMLHttpRequest-Objekt. Es verwendet das <script> tag stattdessen. https://www.w3schools.com/js/js_json_jsonp.asp

  3. Serverseitig - Auf der Serverseite müssen herkunftsübergreifende Anforderungen aktiviert werden. Zuerst erhalten wir die Preflight-Anforderungen (OPTIONEN) und müssen die Anforderung mit dem Statuscode 200 (ok) zulassen.

    Preflight-Anforderungen senden zunächst einen HTTP OPTIONS-Anforderungsheader an die Ressource in der anderen Domäne, um festzustellen, ob die eigentliche Anforderung sicher gesendet werden kann. Standortübergreifende Anforderungen werden auf diese Weise vorab geprüft, da sie Auswirkungen auf Benutzerdaten haben können. Insbesondere wird eine Anforderung vorab geprüft, wenn sie andere Methoden als GET oder POST verwendet. Auch wenn POST wird verwendet, um Anforderungsdaten mit einem anderen Inhaltstyp als application/x-www-form-urlencoded, multipart/form-data oder text/plain zu senden, z POST Anfrage sendet eine XML-Payload mit application/xml oder text/xml an den Server, dann wird die Anfrage vorgeprüft. Es werden benutzerdefinierte Header in der Anfrage festgelegt (z. B. verwendet die Anfrage einen Header wie X) -PINGOTHER)

    Wenn Sie die Feder verwenden , wird das Problem durch Hinzufügen des folgenden Codes behoben. Hier habe ich das csrf-Token deaktiviert, das nicht von Bedeutung ist, um es gemäß Ihrer Anforderung zu aktivieren/deaktivieren.

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

    Wenn Sie die Federsicherung verwenden, verwenden Sie den folgenden Code zusammen mit dem obigen Code.

    @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();
        }
    
    }
    
4
Niru

Beantwortet von mir 

CORS angle js + restEasy on POST

Nun endlich kam ich zu dieser Problemumgehung: Der Grund für die Arbeit mit IE war, dass IE direkt POST sendet, anstatt zuerst eine Preflight-Anfrage zu senden, um nach Erlaubnis zu fragen. Ich weiß aber immer noch nicht, warum der Filter eine OPTIONS-Anfrage nicht verwalten konnte, und sendet standardmäßig Header, die nicht im Filter beschrieben sind (scheint eine Überschreibung für den einzigen Fall zu sein ... vielleicht eine restEasy-Sache ... .)

Also habe ich in meinem Rest-Service einen OPTIONS-Pfad erstellt, der die Antwort neu schreibt und die Header mit Antwortheatern in die Antwort einfügt

Ich bin immer noch auf der Suche nach der sauberen Art und Weise, wenn jemand vor diesem Gesicht stand.

1
J.Doe

Ich bin auf ein ähnliches Problem gestoßen, das Problem war das Backend. Ich habe Node Server (Express) verwendet. Ich hatte eine Get-Anfrage vom Frontend (eckig) wie unten gezeigt

   onGetUser(){
        return this.http.get("http://localhost:3000/user").pipe(map(
            (response:Response)=>{
                const user =response.json();
                return user;
            }
        )) 
    }

Aber es gab den folgenden Fehler The error

Dies ist der Backend-Code, der mit express ohne die Header geschrieben wurde

app.get('/user',async(req,res)=>{
     const user=await getuser();
     res.send(user);
 })

Nach dem Hinzufügen eines Headers zur Methode wurde das Problem behoben

app.get('/user',async(req,res)=>{
    res.header("Access-Control-Allow-Origin", "*");
    const user=await getuser();
    res.send(user);
})

Weitere Informationen zu Aktivieren von CORS auf Node JS

1
Janith Udara

Apache/HTTPD gibt es in den meisten Unternehmen oder wenn Sie Centos/etc zu Hause verwenden. Wenn Sie das haben, können Sie sehr einfach einen Proxy erstellen, um die erforderlichen CORS-Header hinzuzufügen.

Ich habe einen Blog-Eintrag dazu hier , wie ich es in letzter Zeit einige Male erlebt habe. Wichtig ist jedoch, dass Sie Folgendes zu Ihrer Datei /etc/httpd/conf/httpd.conf hinzufügen und sicherstellen, dass Sie bereits "Listen 80" ausführen:

<VirtualHost *:80>
    <LocationMatch "/SomePath">
       ProxyPass http://target-ip:8080/SomePath
       Header add "Access-Control-Allow-Origin" "*"
    </LocationMatch>
</VirtualHost>

Dies stellt sicher, dass alle Anfragen an URLs unter Ihrer-Server-IP: 80/SomePath-Route zu http: // Ziel-IP: 8080/SomePath (die API ohne CORS-Unterstützung) und mit dem richtigen Access-IP zurückkehren. Control-Allow-Origin-Header, damit sie mit Ihrer Web-App arbeiten können.

Natürlich können Sie die Ports ändern und den gesamten Server als Ziel festlegen, anstatt SomePath.

        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);
0
shiva samalla
we can enable CROS in frontend by using ngResourse module.
But most importantly, we should have this piece of code while making ajax 
request in the controller,

$ scope.weatherAPI = $ resource (IHRE API, {Rückruf: "JSON_CALLBACK"}, {get: {Methode: 'JSONP'}}); $ scope.weatherResult = $ scope.weatherAPI.get (IHRE ANFRAGENDATEN, falls vorhanden);

and not to mention, to add ngResourse CDN in script part and add as a dependecy 
in app module.

<script src="https://code.angularjs.org/1.2.16/angular-resource.js"></script>

then use "ngResourse" in app module dependency section like,
var routerApp = angular.module("routerApp", ["ui.router", 'ngResource']);  
0
Alok Ranjan