我使用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);
});
});
但我仍然得到同样的错误。以下是我尝试的一些链接:
XMLHttpRequest cannot load URL. Origin not allowed by 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);
最终编辑
我删除了Authorization标头
headers: {'Authorization': 'Token token=xxxxYYYYZzzz'}
它运行正常。我有我想要的东西。感谢大家参与这个问题
你没有。您发出请求的服务器必须实施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浏览器允许第一个Web页面中包含的脚本访问第二个Web页面中的数据,但前提是两个Web页面具有相同的源。这意味着请求者必须匹配请求站点的确切主机,协议和端口。
我们有多种选择可以解决这个CORS头问题。
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);
});
<script>
标记。 https://www.w3schools.com/js/js_json_jsonp.asp@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();
}
}
我自己回答。
CORS angular js + restEasy on POST
最后我来到这个解决方法:它与IE合作的原因是因为IE直接发送POST而不是首先请求权限的预检请求。但我仍然不知道为什么过滤器无法管理OPTIONS请求并默认发送过滤器中没有描述的标题(似乎只是覆盖了这种情况......也许是一个restEasy的东西.. 。)
所以我在我的休息服务中创建了一个OPTIONS路径,它重写了响应,并使用响应头包含响应中的头
如果有人之前面对这个问题,我仍然在寻找干净利落的方式。
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);
Apache / HTTPD往往在大多数企业中存在,或者如果您在家中使用Centos / etc。所以,如果你有这个,你可以很容易地做代理添加必要的CORS标题。
我有关于这个here的博客文章,因为我最近遭受了很多次。但重要的是将其添加到/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>
这样可以确保所有对-server-ip:80 / SomePath下的URL请求路由到http://target-ip:8080/SomePath(没有CORS支持的API),并且它们返回正确的Access-Control-Allow-Origin标头以允许它们与您的Web一起使用-app。
当然,如果您愿意,可以更改端口并定位整个服务器而不是SomePath。
我们可以使用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>
然后在app模块依赖项部分中使用“ngResourse”
var routerApp = angular.module("routerApp", ["ui.router", 'ngResource']);
我遇到了类似这样的问题,问题在于后端。我正在使用节点服务器(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);
})
您可以获得有关Enabling CORS on Node JS的更多详细信息