ank*_*itr 141 javascript cors angularjs angularjs-http
我使用JavaScript为Flickr照片搜索API创建了一个演示.现在我将它转换为AngularJs.我在互联网上搜索,发现下面的配置.
组态:
myApp.config(function($httpProvider) {
$httpProvider.defaults.useXDomain = true;
delete $httpProvider.defaults.headers.common['X-Requested-With'];
});
Run Code Online (Sandbox Code Playgroud)
服务:
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'}
});
}
});
Run Code Online (Sandbox Code Playgroud)
控制器:
myApp.controller('flickrController', function($scope, dataService) {
$scope.data = null;
dataService.flickrPhotoSearch().then(function(dataResponse) {
$scope.data = dataResponse;
console.log($scope.data);
});
});
Run Code Online (Sandbox Code Playgroud)
但我仍然得到同样的错误.以下是我尝试的一些链接:
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);
Run Code Online (Sandbox Code Playgroud)
最终编辑
我删除了Authorization标头
headers: {'Authorization': 'Token token=xxxxYYYYZzzz'}
它运行正常.我有我想要的东西.感谢大家参与这个问题
Que*_*tin 182
你没有.您发出请求的服务器必须实施CORS才能从您的网站访问中授予JavaScript.您的JavaScript无法授予自己访问其他网站的权限.
Erw*_*win 63
我有一个类似的问题,对我来说,它归结为在接收端的响应中添加以下HTTP标头:
Access-Control-Allow-Headers: Content-Type
Access-Control-Allow-Methods: GET, POST, OPTIONS
Access-Control-Allow-Origin: *
Run Code Online (Sandbox Code Playgroud)
您可能不想*在最后使用,而只使用发送数据的主机的域名.喜欢*.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' });
});
Run Code Online (Sandbox Code Playgroud)
模板:
<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>
Run Code Online (Sandbox Code Playgroud)
出现此问题的原因是 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);
});
Run Code Online (Sandbox Code Playgroud)JSONP - JSONP 是一种发送 JSON 数据的方法,无需担心跨域问题。它不使用 XMLHttpRequest 对象。它使用标签<script>代替。https://www.w3schools.com/js/js_json_jsonp.asp
服务器端- 在服务器端我们需要启用跨源请求。首先,我们将获取预检请求(选项),并且需要允许状态代码为200(正常)的请求。
预检请求首先将 HTTP OPTIONS 请求标头发送到其他域上的资源,以确定实际请求是否可以安全发送。跨站点请求会像这样进行预检,因为它们可能会对用户数据产生影响。特别是,如果请求使用 GET 或 POST 以外的方法,则该请求将被预检。另外,如果 POST 用于发送 Content-Type 不是 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("*");
}
};
}
}
Run Code Online (Sandbox Code Playgroud)
如果您使用 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();
}
}
Run Code Online (Sandbox Code Playgroud)| 归档时间: |
|
| 查看次数: |
363818 次 |
| 最近记录: |