programing

AngularJs에서 CORS를 활성화하는 방법

megabox 2023. 2. 11. 09:06
반응형

AngularJs에서 CORS를 활성화하는 방법

저는 JavaScript for Flickr 사진검색 API를 사용하여 데모를 만들었습니다.이제 AngularJs로 변환합니다.인터넷에서 검색해 보니 아래와 같은 설정이 있습니다.

설정:

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

서비스:

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

컨트롤러:

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

하지만 여전히 같은 오류가 발생했습니다.다음은 제가 시도한 링크입니다.

XMLHttpRequest는 URL을 로드할 수 없습니다. 원본은 Access-Control-Allow-Origin에서 허용되지 않습니다.

http://goo.gl/JuS5B1

넌 아냐.요청하려는 서버는 웹 사이트에서 JavaScript를 허용하기 위해 CORS를 구현해야 합니다.사용 중인 JavaScript는 다른 웹 사이트에 액세스할 수 있는 권한을 스스로 부여할 수 없습니다.

비슷한 문제가 있어서 수신측응답으로 다음과 같은 HTTP 헤더를 추가하는 것으로 요약됩니다.

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

경우 사용하지 것이 수 있습니다.*마지막에는 데이터를 전송하는 호스트의 도메인 이름만 표시됩니다.맘에 들다*.example.com

다만, 이것은 서버의 설정에 액세스 할 수 있는 경우에만 실행할 수 있습니다.

리소스 서비스를 사용하여 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' });
});

템플릿:

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

이 문제는 동일한 오리진 정책인 웹 응용 프로그램보안 모델 정책으로 인해 발생합니다. 이 정책 하에서 웹 브라우저는 첫 번째 웹 페이지에 포함된 스크립트가 두 번째 웹 페이지의 데이터에 액세스할 수 있도록 허용합니다. 단, 두 웹 페이지가 동일한 오리진인 경우에만 해당됩니다.즉, 요청자는 요청 사이트의 정확한 호스트, 프로토콜 및 포트와 일치해야 합니다.

이 CORS 헤더 문제를 해결하기 위해 여러 가지 옵션이 있습니다.

  1. 프록시 사용 - 이 솔루션에서는 요청이 프록시를 통과할 때 동일한 발신원인 것처럼 보이도록 프록시를 실행합니다.노드를 사용하는 경우JS는 어디에서나 cors-anywhere를 사용하여 프록시 작업을 수행할 수 있습니다.https://www.npmjs.com/package/cors-anywhere 를 참조해 주세요.

    :-

    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는 도메인 간 문제를 걱정하지 않고 JSON 데이터를 전송하는 방법입니다.XMLHttpRequest 개체를 사용하지 않습니다.를 사용합니다.<script>태그를 지정합니다.https://www.w3schools.com/js/js_json_jsonp.asp

  3. 서버측 - 서버측에서는, 발신기지간 요구를 유효하게 할 필요가 있습니다.먼저 Preflighted Requests(OPTIONS)를 수신하고 상태 코드 200(ok)인 요청을 허용해야 합니다.

    프리플라이트된 요구는 먼저 HTTP OPTIONS 요청 헤더를 다른 도메인 상의 리소스에 전송하여 실제 요청을 전송해도 안전한지 여부를 판단합니다.교차 사이트 요청은 사용자 데이터에 영향을 미칠 수 있으므로 이와 같이 사전 전송됩니다.특히 GET 또는 POST 이외의 메서드를 사용하는 경우 요구가 프리플라이트 됩니다.또한 POST를 사용하여 응용 프로그램/x-www-form-urlencoded, multipart/form-data 또는 text/plain 이외의 Content-Type을 사용하여 요청 데이터를 보내는 경우(예를 들어 POST 요구가 application/xml 또는 text/xml을 사용하여 XML payload를 서버에 보내는 경우) 해당 요청은 미리 전송됩니다.요청에 커스텀 헤더를 설정합니다(예: 요청은 X-PINGOTHER 등의 헤더를 사용합니다).

    스프링을 사용하는 경우 벨로우 코드를 추가하면 문제가 해결됩니다.여기서는 필요에 따라 활성화/비활성화하지 않는 CSRF 토큰을 비활성화합니다.

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

    스프링 보안을 사용하는 경우 위 코드와 함께 아래 코드를 사용하십시오.

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

이와 같은 문제가 발생했는데, 백엔드에 문제가 있었습니다.노드 서버(Express)를 사용하고 있었습니다.아래와 같이 프런트엔드(angular)로부터 get 요청을 받았습니다.

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

그러나 다음과 같은에러 오류가 발생했습니다.

헤더 없이 express를 사용하여 작성된 백엔드 코드입니다.

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

메서드에 헤더를 추가한 후 문제가 해결되었습니다.

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

노드 JS에서 CORS를 활성화하는 방법에 대한 자세한 내용을 참조하십시오.

이 답변에서는 CORS를 지원하지 않는 API를 회피하기 위한 두 가지 방법을 설명합니다.

  • CORS 프록시 사용
  • API가 JSONP를 지원하는 경우 JSONP 사용

회피책 중 하나는 CORS PROXY를 사용하는 것입니다.

angular.module("app",[])
.run(function($rootScope,$http) { 
     var proxy = "//cors-anywhere.herokuapp.com";
     var url = "http://api.ipify.org/?format=json";
     $http.get(proxy +'/'+ url)
       .then(function(response) {
         $rootScope.response = response.data;
     }).catch(function(response) {
         $rootScope.response = 'ERROR: ' + response.status;
     })     
})
<script src="//unpkg.com/angular/angular.js"></script>
<body ng-app="app">
   Response = {{response}}
</body>

상세한 것에 대하여는, 을 참조해 주세요.


API가 JSONP를 지원하는 경우 JSONP를 사용합니다.

 var url = "//api.ipify.org/";
 var trust = $sce.trustAsResourceUrl(url);
 $http.jsonp(trust,{params: {format:'jsonp'}})
   .then(function(response) {
     console.log(response);
     $scope.response = response.data;
 }).catch(function(response) {
     console.log(response);
     $scope.response = 'ERROR: ' + response.status;
 }) 

PLNKR 데모

상세한 것에 대하여는, 을 참조해 주세요.

나 혼자 대답했어.

CORS 앵글 js + rest POST 시 간단

마지막으로 이 문제를 해결했습니다.IE에서 동작하는 이유는 IE가 먼저 비행 전 요청을 전송하지 않고 직접 POST를 전송하여 허가를 요청하기 때문입니다.그러나 필터가 OPTIONS 요청을 관리하지 못하고 기본적으로 필터에 설명되지 않은 헤더를 보내는 이유는 아직 알 수 없습니다(필터에는 덮어쓰기처럼 보입니다만, 아마 나머지일 수도 있습니다).

그래서 rest 서비스에 OPTIONS 경로를 만들었습니다.응답에 응답 헤더를 사용하여 응답에 헤더를 포함합니다.

누군가 전에 이런 상황에 직면했다면 난 아직도 깨끗한 방법을 찾고 있어.

Apache/HTTPD는 대부분의 기업이나 가정에서 Centos/ 등을 사용하는 경우 주로 사용됩니다.따라서 이러한 기능이 있으면 프록시를 매우 쉽게 실행하여 필요한 CORS 헤더를 추가할 수 있습니다.

최근 몇 번 고생을 해서 블로그에 글을 올렸습니다.다만, 중요한 것은, 이것을 /etc/httpd/conf/httpd.conf 파일에 추가하고, 「Listen 80」을 이미 실행하고 있는 것을 확인하는 것입니다.

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

이를 통해 your-server-ip:80/SomePath 아래의 URL에 대한 모든 요구는 http://target-ip:8080/SomePath(CORS를 지원하지 않는 API)로 라우팅되며 올바른 Access-Control-Allow-Origin 헤더를 사용하여 웹 앱과 연동되도록 합니다.

물론 필요에 따라 포트를 변경하여 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);

ngResourse 모듈을 사용하면 프론트 엔드에서 CORS를 활성화할 수 있습니다.하지만 가장 중요한 것은 컨트롤러에서 Ajax 요청을 할 때 이 코드를 가지고 있어야 한다는 것입니다.

$scope.weatherAPI = $resource(YOUR API,
     {callback: "JSON_CALLBACK"}, {get: {method: 'JSONP'}});
 $scope.weatherResult = $scope.weatherAPI.get(YOUR REQUEST DATA, if any);

또한 스크립트 부분에 ngResourse CDN을 추가하고 앱 모듈에 종속 요소로 추가해야 합니다.

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

그런 다음 앱 모듈 종속성 섹션에서 "ngResourse"를 사용합니다.

var routerApp = angular.module("routerApp", ["ui.router", 'ngResource']);

언급URL : https://stackoverflow.com/questions/23823010/how-to-enable-cors-in-angularjs

반응형