[英]How to enable CORS in AngularJs
我已經使用 JavaScript 為 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);
});
});
但我仍然遇到同樣的錯誤。 以下是我嘗試過的一些鏈接:
你沒有。 您向其發出請求的服務器必須實施 CORS 才能從您的網站訪問權限授予 JavaScript。 您的 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>
出現此問題的原因是 Web 應用程序安全模型策略是同源策略在該策略下,Web 瀏覽器允許第一個網頁中包含的腳本訪問第二個網頁中的數據,但前提是兩個網頁具有相同的來源。 這意味着請求者必須匹配請求站點的確切主機、協議和端口。
我們有多種選擇來解決這個 CORS 標頭問題。
使用代理- 在這個解決方案中,我們將運行一個代理,這樣當請求通過代理時,它看起來就像是某個同源。 如果您使用的是nodeJS ,則可以使用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); });
JSONP - JSONP 是一種發送 JSON 數據而無需擔心跨域問題的方法。它不使用 XMLHttpRequest 對象。它使用<script>
標簽代替。 https://www.w3schools.com/js/js_json_jsonp.asp
服務器端- 在服務器端,我們需要啟用跨域請求。 首先,我們將獲得預檢請求 (OPTIONS),我們需要允許狀態代碼為200 (ok) 的請求。
預檢請求首先向其他域上的資源發送 HTTP OPTIONS 請求標頭,以確定實際請求是否可以安全發送。 跨站點請求是這樣預檢的,因為它們可能會對用戶數據產生影響。 特別是,如果請求使用 GET 或 POST 以外的方法,則它會被預檢。 此外,如果 POST 用於發送內容類型不是 application/x-www-form-urlencoded、multipart/form-data 或 text/plain 的請求數據,例如,如果 POST 請求向服務器發送 XML 負載使用 application/xml 或 text/xml,然后預檢請求。 它在請求中設置自定義標頭(例如,請求使用 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("*"); } }; } }
如果您使用的是 spring security,請使用下面的代碼和上面的代碼。
@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)。 我有一個來自前端(角度)的 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);
})
您可以獲得有關在 Node JS 上啟用 CORS 的更多詳細信息
本人回答。
CORS angular js + restEasy on POST
最后我找到了這個解決方法:它與 IE 一起工作的原因是因為 IE 直接發送一個 POST 而不是首先請求許可的預檢請求。 但我仍然不知道為什么過濾器無法管理 OPTIONS 請求並通過過濾器中未描述的默認標頭發送(似乎只是這種情況的覆蓋......也許是一個restEasy的事情.. .)
所以我在我的休息服務中創建了一個 OPTIONS 路徑,它重寫響應並使用響應頭在響應中包含頭
如果之前有人遇到過這種情況,我仍在尋找干凈的方法來做到這一點。
Apache/HTTPD 往往存在於大多數企業中,或者如果您在家中使用 Centos/etc。 所以,如果你有它,你可以很容易地做一個代理來添加必要的 CORS 標頭。
我對這個博客張貼在這里,因為我用它最近好幾次遭遇。 但重要的一點是將它添加到您的 /etc/httpd/conf/httpd.conf 文件並確保您已經在做“聽 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。
此答案概述了解決不支持 CORS 的 API 的兩種方法:
一種解決方法是使用 CORS 代理:
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>
有關更多信息,請參閱
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;
})
有關更多信息,請參閱
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,並在 app 模塊中添加為依賴項。
<script src="https://code.angularjs.org/1.2.16/angular-resource.js"></script>
然后在應用模塊依賴部分使用“ngResourse”
var routerApp = angular.module("routerApp", ["ui.router", 'ngResource']);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.