如何在 AngularJS 中正确使用 HTTP.GET?具体来说,对于外部 API 调用?

IT技术 javascript angularjs http get cross-domain
2021-03-09 17:09:21

我在controller.js中有以下代码,

var myApp = angular.module('myApp',[]);

myApp.service('dataService', function($http) {
delete $http.defaults.headers.common['X-Requested-With'];
this.getData = function() {
    $http({
        method: 'GET',
        url: 'https://www.example.com/api/v1/page',
        params: 'limit=10, sort_by=created:desc',
        headers: {'Authorization': 'Token token=xxxxYYYYZzzz'}
     }).success(function(data){
         return data
    }).error(function(){
        alert("error");
    });
 }
});

myApp.controller('AngularJSCtrl', function($scope, dataService) {
  $scope.data = dataService.getData();
});

但是,我想我可能在与 CORS 相关的问题上犯了一个错误。你能指出我拨打这个电话的正确方法吗?非常感谢!

6个回答

首先,您的success()处理程序只返回数据,但不会返回给调用者,getData()因为它已经在回调中。 $http是一个返回 a 的异步调用$promise,因此您必须在数据可用时注册一个回调。

我建议在 AngularJS 中查找 Promises 和$q 库,因为它们是在服务之间传递异步调用的最佳方式。

为简单起见,以下是使用调用控制器提供的函数回调重写的相同代码:

var myApp = angular.module('myApp',[]);

myApp.service('dataService', function($http) {
    delete $http.defaults.headers.common['X-Requested-With'];
    this.getData = function(callbackFunc) {
        $http({
            method: 'GET',
            url: 'https://www.example.com/api/v1/page',
            params: 'limit=10, sort_by=created:desc',
            headers: {'Authorization': 'Token token=xxxxYYYYZzzz'}
        }).success(function(data){
            // With the data succesfully returned, call our callback
            callbackFunc(data);
        }).error(function(){
            alert("error");
        });
     }
});

myApp.controller('AngularJSCtrl', function($scope, dataService) {
    $scope.data = null;
    dataService.getData(function(dataResponse) {
        $scope.data = dataResponse;
    });
});

现在,$http实际上已经返回了 $promise,因此可以重写:

var myApp = angular.module('myApp',[]);

myApp.service('dataService', function($http) {
    delete $http.defaults.headers.common['X-Requested-With'];
    this.getData = function() {
        // $http() returns a $promise that we can add handlers with .then()
        return $http({
            method: 'GET',
            url: 'https://www.example.com/api/v1/page',
            params: 'limit=10, sort_by=created:desc',
            headers: {'Authorization': 'Token token=xxxxYYYYZzzz'}
         });
     }
});

myApp.controller('AngularJSCtrl', function($scope, dataService) {
    $scope.data = null;
    dataService.getData().then(function(dataResponse) {
        $scope.data = dataResponse;
    });
});

最后,还有更好的方法来配置$http服务来处理用于config()设置$httpProvider. 查看$http 文档以获取示例。

我使用的.then()是 promise 接口,它与.success()链式接口基本相同.success/.error 基本上不推荐用于Promise
2021-05-03 17:09:21
@Kevin:我是 ANG 新手,我不清楚,为什么不在重新编写的代码中在服务中使用 .success 和 .error 方法?我们需要在控制器中使用它吗?如何 ?任何示例来显示成功/错误和数据,配置参数?
2021-05-18 17:09:21

我建议你使用 Promise

myApp.service('dataService', function($http,$q) {

  delete $http.defaults.headers.common['X-Requested-With'];
  this.getData = function() {
     deferred = $q.defer();
     $http({
         method: 'GET',
         url: 'https://www.example.com/api/v1/page',
         params: 'limit=10, sort_by=created:desc',
         headers: {'Authorization': 'Token token=xxxxYYYYZzzz'}
     }).success(function(data){
         // With the data succesfully returned, we can resolve promise and we can access it in controller
         deferred.resolve();
     }).error(function(){
          alert("error");
          //let the function caller know the error
          deferred.reject(error);
     });
     return deferred.promise;
  }
});

所以在您的控制器中,您可以使用该方法

myApp.controller('AngularJSCtrl', function($scope, dataService) {
    $scope.data = null;
    dataService.getData().then(function(response) {
        $scope.data = response;
    });
});

promises 是 angularjs 的强大功能,如果您想避免嵌套回调,它非常方便。

我完全按照上述操作,但最终在控制器中出现错误“无法读取未定义的属性 'then'”。修复:完全删除延迟/Promise并简单地返回 $http(<content go here>); 如第一条评论中所述
2021-04-30 17:09:21
使用.then上的$ HTTPPromise不会直接返回数据,如.success
2021-05-03 17:09:21
$http 已经返回了一个Promise。将 $http 包装在另一个 promise 中是多余的。
2021-05-15 17:09:21

无需与 $http Promise,我只使用它有两个回报:

 myApp.service('dataService', function($http) {
   this.getData = function() {
      return $http({
          method: 'GET',
          url: 'https://www.example.com/api/v1/page',
          params: 'limit=10, sort_by=created:desc',
          headers: {'Authorization': 'Token token=xxxxYYYYZzzz'}
      }).success(function(data){
        return data;
      }).error(function(){
         alert("error");
         return null ;
      });
   }
 });

在控制器中

 myApp.controller('AngularJSCtrl', function($scope, dataService) {
     $scope.data = null;
     dataService.getData().then(function(response) {
         $scope.data = response;
     });
 }); 

试试这个

myApp.config(['$httpProvider', function($httpProvider) {
        $httpProvider.defaults.useXDomain = true;
        delete $httpProvider.defaults.headers.common['X-Requested-With'];
    }
]);

仅仅设置 useXDomain = true 是不够的。AJAX 请求也与 X-Requested-With 标头一起发送,这表明它们是 AJAX。删除标头是必要的,因此服务器不会拒绝传入的请求。

所以你需要使用我们所说的promise。在此处阅读 angular 如何处理它,https://docs.angularjs.org/api/ng/service/ $q。改变我们的 $http 支持Promise,所以在你的情况下,我们会做这样的事情,

(function() {
  "use strict";
  var serviceCallJson = function($http) {

      this.getCustomers = function() {
        // http method anyways returns promise so you can catch it in calling function
        return $http({
            method : 'get',
            url : '../viewersData/userPwdPair.json'
          });
      }

  }

  var validateIn = function (serviceCallJson, $q) {

      this.called = function(username, password) {
          var deferred = $q.defer(); 
          serviceCallJson.getCustomers().then( 
            function( returnedData ) {
              console.log(returnedData); // you should get output here this is a success handler
              var i = 0;
              angular.forEach(returnedData, function(value, key){
                while (i < 10) {
                  if(value[i].username == username) {
                    if(value[i].password == password) {
                     alert("Logged In");
                    }
                  }
                  i = i + 1;
                }
              });
            }, 
            function() {

              // this is error handler
            } 
          );
          return deferred.promise;  
      }

  }

  angular.module('assignment1App')
    .service ('serviceCallJson', serviceCallJson)

  angular.module('assignment1App')
  .service ('validateIn', ['serviceCallJson', validateIn])

}())