Angular Cross-Origin请求CORS失败,但节点http.get()成功返回

时间:2015-03-22 23:24:06

标签: 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 = ""
    response.on("data", function (chunk) {
        buffer += chunk;
    });
    response.on("end", function (err) {
        console.log(buffer);
        console.log("\n");
    });
});

我使用节点http-server运行我的角度应用程序,其中包含以下参数

"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
    };
});

控制器可以解析w3schools URL,但是在传递asterank URL时它会一直返回CORS错误。 我的应用程序可以在本网站(下方)中为CORS提供其他补救措施。

通过Firefox检查GET请求表明标头未添加到GET请求中。但除此之外,我不知道如何解决这个问题。感谢有兴趣通过Angular学习的人。

我尝试过使用$ 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'];
    });

4 个答案:

答案 0 :(得分:4)

你应该理解一件简单的事情:尽管那些http模块看起来有些相似,但它们与CORS完全不同。

实际上,node.js http.get()与CORS无关。它是您的服务器发出请求 - 与浏览器在其位置栏中输入此URL并打开命令时的操作方式相同。用户代理是不同的,是的,但过程通常是相同的:客户端访问位于外部服务器上的页面。

现在请注意与角度$http.get()的不同之处:客户端会打开一个运行脚本的页面,此脚本会尝试访问位于外部服务器上的页面。换句话说,此请求在另一个页面的上下文中运行 - 位于其自己的域中。除非外部服务器允许此域在客户端代码中访问它,否则它是不可能的 - 这是CORS的重点毕竟。

有不同的解决方法:JSONP - 基本上意味着将响应包装到函数调用中 - 是一种可能的方法。但它具有与其他解决方法相同的关键点 - 它应该允许这种形式的通信的外部服务器。否则,您的JSONP请求将被忽略:服务器发送回常规JSON,这在尝试将其作为函数调用进行处理时会导致错误。

底线:除非外部服务器愿意就此问题进行合作,否则您无法在客户端应用程序中使用其数据 - 除非您通过服务器传递此数据(这将像代理一样。)

答案 1 :(得分:1)

Asterank现在允许对其API的跨源请求。您不必担心上面发布的这些变通办法。一个简单的$ http.get(http://www.asterank.com/api/kepler?query= {" PER":{" $ lt":1.02595675," $ gt":0.67125}}&限制= 10') 现在会工作的。不需要标题。我上周通过电子邮件向他们发送了关于此问题的电子邮件,他们回复并配置了他们的服务器以允许所有原始请求。

来自Asterank的精确电子邮件回复:"我刚为Asterank启用了CORS(即Access-Control-Allow-Origin *)。希望这会有所帮助!"

答案 2 :(得分:0)

昨天我和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>

似乎也可以使用您在上面发布的网址。

ObjectA:0.017DEC:50.2413KMAG:10.961KOI:72.01MSTAR:1.03PER:0.8374903RA:19.04529ROW:31RPLANET:1.38RSTAR:1T0:64.57439TPLANET:1903TSTAR:5627UPER:0.0000015UT0:0.00026

我还应该在chrome中添加CORS plugin。我并没有像角度那样深入研究这个问题。我发现一个基本的HTML可以解决这些CORS限制,这只是一个解决方法,直到我有更多的时间来理解这个问题。

答案 3 :(得分:0)

经过大量的环顾四周。我找到的最好的本地解决方案是npm模块CORS-anywhere。用它来创建AngularJS AWS Cloudsearch Demo