Ajax调用外部API来获取JSON - 使用JSONP

时间:2014-09-12 19:16:27

标签: ajax json angularjs

我需要对外部API执行Ajax调用以获取JSON格式的数据,但我没有得到任何结果。

我有这个控制器:

angular.module('myApp').controller('myCtrl', function($scope, MyService) {

        $scope.list = MyService.fetchAll();
});

这个服务,向另一个域发出Ajax请求:

var MyService = function($http) {
    this.fetchAll = function() {
        console.log('here1');

        $http.jsonp('http://other.domain.com/list/?allback=JSON_CALLBACK').success(function(data) 
            console.log('here2');
            return angular.fromJson(data);
        }).error(function(data, status, headers, config) {
            console.log('here3');
            console.log(status);
        });
    };
};

angular.module('myApp').service('MyService', MyService);

我的Json回复只是:

[1,2,3,4,5]

当执行代码/请求时,我没有得到结果除外,.success()中的代码永远不会被执行。我进入控制台:

here1
here3
404 

有关如何实施此方法的最佳方法的任何建议将不胜感激。我是新手。

3 个答案:

答案 0 :(得分:1)

请记住,外部json请求是一个异步操作,这是你问题的根源,当你调用'fetchAll()'时,它不会等待请求完成并返回值。要纠正这一点,您必须从您的服务中返回一份承诺,并将其数据分配给它的“非常”功能。

var MyService = function($http, $q) {
    this.fetchAll = function() {
        var deferred = $q.defer();


        $http.jsonp('http://other.domain.com/list/?allback=JSON_CALLBACK').success(function(data){ 
            console.log('here2');
            deferred.resolve(angular.fromJson(data));
        }).error(function(data, status, headers, config) {
            console.log('here3');
            deferred.reject(status);
        });

        return deferred.promise;
    };
return this;
};

在您的控制器上,执行此操作:

angular.module('myApp').controller('myCtrl', function($scope, MyService) {
    MyService.fetchAll.then(function(data){
        $scope.list = data;
    })
}, function(error){
    console.log(error);
    // Decide what to do with your $scope.list in case of an error
    $scope.list = null;
});

答案 1 :(得分:1)

您的console.log(status)打印404表示:

  

404或Not Found错误消息是HTTP标准响应代码   表明客户端能够与给定的通信   服务器,但服务器找不到请求的内容。

仔细检查网址。

您可以使用工厂进行ajax调用: (样本http://jsfiddle.net/ty69u6tL/4/

<强> FACTORY:

app.factory('MyService', function ($http, $q) {

    /////////////////////////////////////////////////////////////
    // put your url here:////////////////////////////////////////
    /////////////////////////////////////////////////////////////
    var url = "http://public-api.wordpress.com/rest/v1/sites/wtmpeachtest.wordpress.com/posts?callback=JSON_CALLBACK";


    this.fetchAll = function () {
        var deferred = $q.defer();
        console.log('here1');
        $http.jsonp(url).success(function (data) {
            console.log('here2');
            deferred.resolve(angular.fromJson(data));
        }).error(function (data, status, headers, config) {
            console.log('here3');
            console.log(status);
            deferred.reject(data, status, headers, config);
        });
        return deferred.promise;
    };
    return this;
});

<强>控制器:

app.controller('jsonp_example', function ($scope, MyService) {
    $scope.data = {};

    $scope.doRequest = function () {
        MyService.fetchAll().then(onSucess, onError);

        function onSucess(response) {
            $scope.data = response;
        }

        function onError() {
            alert("Cant get data ");
        }        
    };
 });

<强> HTML *

<div ng-app="app">
    <div ng-controller="jsonp_example">
        <button ng-click="doRequest()">Make JSONP request</button> <pre> {{data | json}}</pre>

    </div>
</div>

答案 2 :(得分:1)

出于存档目的,我最终按照以下方式做了(我个人认为这是最简单的方法):

在我的服务中我有这个:

this.fetchAll = function() {

        return $http.jsonp("<here API Endpoint>").then(function(response){
                return response.data;
        });
};

在我的控制器中:

MyService.fetchAll().then(function(data) {
    requestResult = data;
});

只是一个注释:主要问题是请求的API不返回回调引用,只返回JSON [1,2,3,4,5]。而是需要返回类似“JSON_CALLBACK([1,2,3,4,5])”

的内容