Javascript 角度跨原点请求CORS失败,但节点http.get()成功返回

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 =

我正在尝试使用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 = ""
    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.js
http.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