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



我正在尝试使用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
    };
});

控制器可以解析w3schools URL,但在传递星号URL时,它始终返回CORS错误。我的应用程序利用了本网站上建议的其他CORS补救措施(如下)。

通过Firefox检查GET请求表明,没有将头添加到GET请求中。但除此之外,我不知道如何补救。感谢通过Angular学习的人提供帮助。

我尝试过使用$http.json()。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模块看起来有些相似,但它们在CORS方面完全不同。

实际上,node.js的http.get()与CORS无关。是你的服务器发出请求,就像你在浏览器的位置栏中键入这个URL并命令打开它一样。是的,用户代理不同,但通常的过程是一样的:客户端访问位于外部服务器上的页面。

现在注意angular的$http.get()的区别:客户端打开一个运行脚本的页面,该脚本试图访问位于外部服务器上的页面。换句话说,这个请求在另一个页面的上下文中运行,该页面位于它自己的域中。除非外部服务器允许该域在客户端代码中访问它,否则这是不可能的——毕竟这就是CORS的意义所在。

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

底线是:除非外部服务器愿意在这件事上合作,否则你将无法在客户端应用程序中使用它的数据——除非你通过你的服务器(它将充当代理)传递这些数据。

Asterank现在允许跨来源请求到其API。你再也不用担心上面发布的这些变通方法了。一个简单的$http.get(http://www.asterank.com/api/kepler?query={"PER":{"$lt":1.02595675,"$gt":0.67125}};极限=10')现在就可以工作了。不需要标头。我上周就这个问题给他们发了电子邮件,他们做出了回应,并将服务器配置为允许所有来源请求。

Asterank的确切电子邮件回复:"我刚刚为Asterank启用了CORS(即访问控制允许来源*)。希望这有帮助!"

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

似乎与你在上面发布的网址也一样。。

目标A:0.017DEC:50.2413KMAG:10.961KOI:72.01MSTAR:1.03PER:0.8374903RA:19.04529行:31RP局域网:1.38RSTAR:1T0:64.57439TP局域网:1903TSTAR:5627UPER:0.0000015UT0:0.00026

我还应该补充一点,在chrome中,您需要CORS插件。我没有深入研究这个问题。我发现一个基本的html可以绕过这些CORS限制,这只是一个变通办法,直到我有更多的时间来理解这个问题。

看了很多遍之后。我找到的最好的本地解决方案是任何地方的npm模块CORS。使用它创建AngularJS AWS云搜索演示。

最新更新