我使用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/
EDIT:
我在@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);
Final Edit
我删除了Authorization标头
headers: {'Authorization': 'Token token=xxxxYYYYZzzz'}
它运行正常 . 我有我想要的东西 . 感谢大家参与这个问题
6 回答
你没有 . 您发出请求的服务器必须实施CORS才能从您的网站访问中授予JavaScript . 您的JavaScript无法授予自己访问其他网站的权限 .
我有一个类似的问题,对我来说,它归结为在 receiving end 的 response 添加以下HTTP标头:
您可能不希望最后使用
*
,而只使用发送数据的主机的域名 . 喜欢*.example.com
但这只有在您可以访问服务器配置时才可行 .
尝试使用资源服务来使用flickr jsonp:
模板:
出现此问题是因为Web应用程序安全模型策略是 Same Origin Policy 在策略下,Web浏览器允许第一个Web页面中包含的脚本访问第二个Web页面中的数据,但前提是两个Web页面具有相同的源 . 这意味着请求者必须匹配请求站点的确切主机,协议和端口 .
我们有多种选择可以解决这个CORS头问题 .
Example : -
JSONP - JSONP是一种发送JSON数据的方法,无需担心跨域问题 . 它不使用XMLHttpRequest对象 . 它使用
<script>
标记 . https://www.w3schools.com/js/js_json_jsonp.aspServer Side - 在服务器端,我们需要启用跨源请求 . 首先,我们将获得Preflighted请求(OPTIONS),我们需要允许状态代码 200 (ok)的请求 .
预检请求首先向另一个域上的资源发送HTTP OPTIONS请求标头,以确定实际请求是否可安全发送 . 跨站点请求是这样预检的,因为它们可能对用户数据有影响 . 特别是,如果请求使用GET或POST以外的方法,则会对其进行预检 . 此外,如果POST用于发送具有除application / x-www-form-urlencoded,multipart / form-data或text / plain之外的Content-Type的请求数据,例如,如果POST请求使用application / xml或text / xml将XML有效负载发送到服务器,则该请求将被预检 . 它在请求中设置自定义标头(例如,请求使用标头,如X-PINGOTHER)
如果您正在使用 spring ,只需添加以下代码即可解决问题 . 在这里,我已根据您的要求禁用了与启用/禁用无关的csrf令牌 .
如果您使用 spring 安全使用下面的代码以及上面的代码 .
我自己回答 .
CORS angular js + restEasy on POST
最后我来到这个解决方法:它与IE一起工作的原因是因为IE直接发送POST而不是首先请求权限的预检请求 . 但我仍然不知道为什么过滤器无法管理OPTIONS请求并默认发送过滤器中未描述的 Headers (似乎只是覆盖了这种情况......也许是一个restEasy的东西.. . )
所以我在我的休息服务中创建了一个OPTIONS路径,它重写响应并使用响应头包含响应中的头
如果有人之前面对这个,我仍然在寻找干净的方式去做 .