Javascript 角度跨原点请求CORS失败,但节点http.get()成功返回
我正在尝试使用AngularJS访问API。我已经用以下节点代码检查了API功能。这就排除了错误在于Javascript 角度跨原点请求CORS失败,但节点http.get()成功返回,javascript,angularjs,node.js,cors,Javascript,Angularjs,Node.js,Cors,我正在尝试使用AngularJS访问API。我已经用以下节点代码检查了API功能。这就排除了错误在于 var http = require("http"); url = 'http://www.asterank.com/api/kepler?query={"PER":{"$lt":1.02595675,"$gt":0.67125}}&limit=10'; var request = http.get(url, function (response) { var buffer =
var http = require("http");
url = 'http://www.asterank.com/api/kepler?query={"PER":{"$lt":1.02595675,"$gt":0.67125}}&limit=10';
var request = http.get(url, function (response) {
var buffer = ""
response.on("data", function (chunk) {
buffer += chunk;
});
response.on("end", function (err) {
console.log(buffer);
console.log("\n");
});
});
我使用节点http服务器运行angular应用程序,参数如下
"start": "http-server --cors -a localhost -p 8000 -c-1"
我的角度控制器如下所示
app.controller('Request', function($scope, $http){
// functional URL = http://www.w3schools.com/website/Customers_JSON.php
$scope.test = "functional";
$scope.get = function(){
$http.get('http://www.asterank.com/api/kepler?query={"PER":{"$lt":1.02595675,"$gt":0.67125}}&limit=10',{
params: {
headers: {
//'Access-Control-Allow-Origin': '*'
'Access-Control-Request-Headers' : 'access-control-allow-origin'
}
}
})
.success(function(result) {
console.log("Success", result);
$scope.result = result;
}).error(function() {
console.log("error");
});
// the above is sending a GET request rather than an OPTIONS request
};
});
控制器可以解析W3URL,但当传递到asterank URL时,它始终返回CORS错误。
我的应用程序可在此网站(如下)上使用针对CORS建议的其他补救措施
通过Firefox检查GET请求,会发现没有将头添加到GET请求中。但除此之外,我不知道如何补救。感谢有人通过学习来帮助他们
我尝试过使用$http.jsonp()。GET请求成功执行(通过网络),但angular方法返回.error()函数
var app = angular.module('sliderDemoApp', ['ngSlider', 'ngResource']);
.config(function($httpProvider) {
//Enable cross domain calls
$httpProvider.defaults.useXDomain = true;
delete $httpProvider.defaults.headers.common['X-Requested-With'];
});
您应该理解一件简单的事情:尽管那些
http
模块看起来有些相似,但它们在COR方面是完全不同的
实际上,node.jshttp.get()
与CORS无关。是您的服务器发出请求——就像您的浏览器在其位置栏中键入此URL并命令打开它时所做的那样。是的,用户代理是不同的,但过程通常是相同的:客户机访问位于外部服务器上的页面
现在请注意angular的$http.get()
:客户端打开一个运行脚本的页面,该脚本尝试访问位于外部服务器上的页面。换句话说,此请求在另一个页面的上下文中运行—位于其自己的域中。除非外部服务器允许该域在客户端代码中访问它,否则这是不可能的——毕竟,这是CORS的要点
有不同的解决方法:JSONP——基本上意味着将响应包装到函数调用中——是一种可能的方法。但是,它与其他解决方法具有相同的关键点——外部服务器应该允许这种形式的通信。否则,您对JSONP的请求将被忽略:服务器发回一个常规JSON,这在尝试将其作为函数调用处理时会导致错误
一句话:除非外部服务器愿意在这个问题上进行合作,否则您将无法在客户端应用程序中使用其数据-除非您通过服务器(将充当代理)传递此数据。我昨天与CORS有类似的问题,我使用了一个表单来解决它,希望这会有所帮助
.config(function($httpProvider){
delete $httpProvider.defaults.headers.common['X-Requested-With'];
$httpProvider.defaults.headers.common = {};
$httpProvider.defaults.headers.post = {};
$httpProvider.defaults.headers.put = {};
$httpProvider.defaults.headers.patch = {};
})
.controller('FormCtrl', function ($scope, $http) {
$scope.data = {
q: "test"//,
// z: "xxx"
};
$scope.submitForm = function () {
var filters = $scope.data;
var queryString ='';
for (i in filters){
queryString=queryString + i+"=" + filters[i] + "&";
}
$http.defaults.useXDomain = true;
var getData = {
method: 'GET',
url: 'https://YOUSEARCHDOMAIN/2013-01-01/search?' + queryString,
headers: {
'Content-Type': 'application/json; charset=utf-8'
}
};
console.log("posting data....");
$http(getData).success(function(data, status, headers, config) {
console.log(data);
}).error(function(data, status, headers, config) {
});
}
})
<div ng-controller="FormCtrl">
<form ng-submit="submitForm()">
First names: <input type="text" name="form.firstname">
Email Address: <input type="text" ng-model="form.emailaddress">
<button>bmyutton</button>
</form>
</div>
.config(函数($httpProvider){
删除$httpProvider.defaults.headers.common['X-Requested-With'];
$httpProvider.defaults.headers.common={};
$httpProvider.defaults.headers.post={};
$httpProvider.defaults.headers.put={};
$httpProvider.defaults.headers.patch={};
})
.controller('FormCtrl',函数($scope,$http){
$scope.data={
q:“测试”//,
//z:“xxx”
};
$scope.submitForm=函数(){
变量过滤器=$scope.data;
var queryString='';
用于(过滤器中的i){
queryString=queryString+i+“=”+过滤器[i]+“&”;
}
$http.defaults.useXDomain=true;
var getData={
方法:“GET”,
网址:'https://YOUSEARCHDOMAIN/2013-01-01/search?“+queryString,
标题:{
“内容类型”:“应用程序/json;字符集=utf-8”
}
};
console.log(“发布数据…”);
$http(getData).success(函数(数据、状态、标题、配置){
控制台日志(数据);
}).error(函数(数据、状态、标题、配置){
});
}
})
名字:
电邮地址:
布米尤顿
似乎与您在上面发布的url一起工作
对象A:0.017DEC:50.2413KMAG:10.961KOI:72.01MSTAR:1.03PER:0.8374903RA:19.04529ROW:31RPLANET:1.38RSTAR:1T0:64.57439TPLANET:1903TSTAR:5627UPER:0.000015UT0:0.00026
我还要补充一点,在chrome中,您需要。我对这个问题的研究没有像我对angular那样深入。我发现一个基本的html可以绕过这些CORS限制,这只是一个解决办法,直到我有更多的时间来理解这个问题。经过大量的研究。我找到的最好的本地解决方案是npm模块CORS anywhere。用于创建。Asterank现在允许跨源请求到其API。你不必再担心上面提到的这些解决方法了。一个简单的$http.get({“PER”:{“$lt”:1.02595675,“$gt”:0.67125}}&limit=10') 现在可以了。不需要标题。我上周向他们发送了有关此问题的电子邮件,他们响应并配置了服务器以允许所有原始请求
Asterank的准确电子邮件回复:“我刚刚为Asterank启用了CORS(即访问控制允许源代码*)。希望这有帮助!”谢谢,这确实有助于澄清节点成功而angular无法访问它的机制。非常感谢您花时间详细说明差异表单不是解决方法:除非您提到的插件已安装并激活,否则您将遇到相同的问题。您可以确认我添加了您提到的插件,并且我的代码在没有使用表单解决方法的情况下工作,并且是插件发挥了神奇的作用。在实现必要的后端之前,这无疑是一个有用的hack