AngularJ에서 CORS를 활성화하는 방법
Flickr 사진 검색 API 용 JavaScript를 사용하여 데모를 만들었습니다. 이제 AngularJ로 변환하고 있습니다. 인터넷에서 검색했으며 아래 구성을 찾았습니다.
구성 :
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://samurails.com/tutorial/cors-with-angular-js-and-sinatra/
편집하다:
@Quentin의 제안에 따라 node.js에 프록시 서버를 만들었습니다.
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);
최종 편집
인증 헤더를 제거했습니다
headers: {'Authorization': 'Token token=xxxxYYYYZzzz'}
그리고 그것은 잘 돌아가고 있습니다. 내가 원하는 것을 얻었습니다. 이 질문에 참여해 주셔서 감사합니다.
당신은하지 않습니다. 요청하는 서버는 CORS를 구현하여 웹 사이트 액세스에서 JavaScript를 부여해야합니다. 자바 스크립트는 다른 웹 사이트에 액세스 할 수있는 권한을 스스로 부여 할 수 없습니다.
비슷한 문제가 있었고 수신 측 의 응답 으로 다음 HTTP 헤더를 추가하는 것으로 요약했습니다 .
Access-Control-Allow-Headers: Content-Type
Access-Control-Allow-Methods: GET, POST, OPTIONS
Access-Control-Allow-Origin: *
*
끝에는 사용하지 말고 데이터를 보내는 호스트의 도메인 이름 만 사용하는 것이 좋습니다 . 처럼*.example.com
그러나 이것은 서버 구성에 액세스 할 수있는 경우에만 가능합니다.
리소스 서비스를 사용하여 깜박임 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>
이 문제는 동일한 원본 정책 인 웹 응용 프로그램 보안 모델 정책으로 인해 발생합니다. 정책 에서 웹 브라우저는 첫 번째 웹 페이지에 포함 된 스크립트가 두 번째 웹 페이지의 데이터에 액세스 할 수 있지만 두 웹 페이지의 원본이 동일한 경우에만 가능합니다. 즉, 요청자는 요청 호스트의 정확한 호스트, 프로토콜 및 포트와 일치해야합니다.
We have multiple options to over come this CORS header issue.
Using Proxy - In this solution we will run a proxy such that when request goes through the proxy it will appear like it is some same origin. If you are using the nodeJS you can use cors-anywhere to do the proxy stuff. https://www.npmjs.com/package/cors-anywhere.
Example:-
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); });
JSONP - JSONP is a method for sending JSON data without worrying about cross-domain issues.It does not use the XMLHttpRequest object.It uses the
<script>
tag instead. https://www.w3schools.com/js/js_json_jsonp.aspServer Side - On server side we need to enable cross-origin requests. First we will get the Preflighted requests (OPTIONS) and we need to allow the request that is status code 200 (ok).
Preflighted requests first send an HTTP OPTIONS request header to the resource on the other domain, in order to determine whether the actual request is safe to send. Cross-site requests are preflighted like this since they may have implications to user data. In particular, a request is preflighted if it uses methods other than GET or POST. Also, if POST is used to send request data with a Content-Type other than application/x-www-form-urlencoded, multipart/form-data, or text/plain, e.g. if the POST request sends an XML payload to the server using application/xml or text/xml, then the request is preflighted. It sets custom headers in the request (e.g. the request uses a header such as X-PINGOTHER)
If you are using the spring just adding the bellow code will resolves the issue. Here I have disabled the csrf token that doesn't matter enable/disable according to your requirement.
@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("*"); } }; } }
If you are using the spring security use below code along with above 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(); } }
I encountered a similar problem like this, problem was with the backend . I was using node server(Express). I had a get request from the frontend(angular) as shown below
onGetUser(){
return this.http.get("http://localhost:3000/user").pipe(map(
(response:Response)=>{
const user =response.json();
return user;
}
))
}
But it gave the following error
This is the backend code written using express without the headers
app.get('/user',async(req,res)=>{
const user=await getuser();
res.send(user);
})
After adding a header to the method problem was solved
app.get('/user',async(req,res)=>{
res.header("Access-Control-Allow-Origin", "*");
const user=await getuser();
res.send(user);
})
You can get more details about Enabling CORS on Node JS
Answered by myself.
CORS angular js + restEasy on POST
Well finally I came to this workaround: The reason it worked with IE is because IE sends directly a POST instead of first a preflight request to ask for permission. But I still don't know why the filter wasn't able to manage an OPTIONS request and sends by default headers that aren't described in the filter (seems like an override for that only case ... maybe a restEasy thing ...)
So I created an OPTIONS path in my rest service that rewrites the reponse and includes the headers in the response using response header
I'm still looking for the clean way to do it if anybody faced this before.
Apache/HTTPD tends to be around in most enterprises or if you're using Centos/etc at home. So, if you have that around, you can do a proxy very easily to add the necessary CORS headers.
I have a blog post on this here as I suffered with it quite a few times recently. But the important bit is just adding this to your /etc/httpd/conf/httpd.conf file and ensuring you are already doing "Listen 80":
<VirtualHost *:80>
<LocationMatch "/SomePath">
ProxyPass http://target-ip:8080/SomePath
Header add "Access-Control-Allow-Origin" "*"
</LocationMatch>
</VirtualHost>
This ensures that all requests to URLs under your-server-ip:80/SomePath route to http://target-ip:8080/SomePath (the API without CORS support) and that they return with the correct Access-Control-Allow-Origin header to allow them to work with your web-app.
Of course you can change the ports and target the whole server rather than SomePath if you like.
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);
we can enable CORS in the frontend by using the ngResourse module. But most importantly, we should have this piece of code while making the ajax request in the controller,
$scope.weatherAPI = $resource(YOUR API,
{callback: "JSON_CALLBACK"}, {get: {method: 'JSONP'}});
$scope.weatherResult = $scope.weatherAPI.get(YOUR REQUEST DATA, if any);
Also, you must add ngResourse CDN in the script part and add as a dependency in the app module.
<script src="https://code.angularjs.org/1.2.16/angular-resource.js"></script>
Then use "ngResourse" in the app module dependency section
var routerApp = angular.module("routerApp", ["ui.router", 'ngResource']);
참고URL : https://stackoverflow.com/questions/23823010/how-to-enable-cors-in-angularjs
'Programing' 카테고리의 다른 글
String.split에 파이프 구분 기호가 필요한 이유는 무엇입니까? (0) | 2020.06.20 |
---|---|
인수로 전달 된 TypeScript 객체의 기본값 설정 (0) | 2020.06.20 |
Eclipse에서 전체 프로젝트를 찾거나 바꾸는 방법이 있습니까? (0) | 2020.06.20 |
Bash에서 단일 및 이중 대괄호의 차이점 (0) | 2020.06.20 |
브라우저 창 닫기 이벤트를 캡처하는 방법은 무엇입니까? (0) | 2020.06.20 |