it-swarm.com.ru

Как правильно использовать HTTP.GET в AngularJS? В частности, для внешнего вызова API?

У меня есть следующий код в 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. Не могли бы вы указать мне правильный способ сделать этот звонок? Большое спасибо!

37
Anand Ram

Во-первых, ваш обработчик success() просто возвращает данные, но они не возвращаются вызывающей стороне getData(), поскольку они уже находятся в обратном вызове. $http - это асинхронный вызов, который возвращает $promise, поэтому вы должны зарегистрировать обратный вызов, когда данные будут доступны.

Я бы порекомендовал поискать Promises и библиотеку $ q в AngularJS, поскольку они являются лучшим способом передачи асинхронных вызовов между службами.

Для простоты вот тот же код, переписанный с помощью функции обратного вызова, предоставляемой вызывающим контроллером:

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 уже возвращает $ обещание, так что это можно переписать:

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 документацию для примеров.

77
Kevin Stone

Я предлагаю вам использовать 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;
    });
});

обещания - это мощная особенность angularjs, и это особенно удобно, если вы хотите избежать вложенных обратных вызовов. 

9
Emil Reña Enriquez

Не нужно обещать с $ http, я использую его только с двумя возвратами:

 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;
     });
 }); 
3
AlainIb

Попробуй это

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

Недостаточно просто установить useXDomain = true. Запрос AJAX также отправляется с заголовком X-Requested-With, который указывает, что он является AJAX. Удаление заголовка необходимо, чтобы сервер не отклонял входящий запрос.

2
ShibinRagh

Поэтому вам нужно использовать то, что мы называем обещанием. Прочитайте, как angular справляется с этим здесь, https://docs.angularjs.org/api/ng/service/ $ q. Превращает наши обещания $ http поддержки по своей сути, поэтому в вашем случае мы сделаем что-то вроде этого,

(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])

}())
1
kishanio

Использование Google Finance в качестве примера для получения последней цены закрытия тикера и обновленной даты и времени. Вы можете посетить YouTiming.com для исполнения во время выполнения.

Сервис:

MyApp.service('getData', 
  [
    '$http',
    function($http) {

      this.getQuote = function(ticker) {
        var _url = 'https://www.google.com/finance/info?q=' + ticker;
        return $http.get(_url); //Simply return the promise to the caller
      };
    }
  ]
);

Контроллер:

MyApp.controller('StockREST', 
  [
    '$scope',
    'getData', //<-- the service above
    function($scope, getData) {
      var getQuote = function(symbol) {
        getData.getQuote(symbol)
        .success(function(response, status, headers, config) {
          var _data = response.substring(4, response.length);
          var _json = JSON.parse(_data);
          $scope.stockQuoteData = _json[0];
          // ticker: $scope.stockQuoteData.t
          // last price: $scope.stockQuoteData.l
          // last updated time: $scope.stockQuoteData.ltt, such as "7:59PM EDT"
          // last updated date & time: $scope.stockQuoteData.lt, such as "Sep 29, 7:59PM EDT"
        })
        .error(function(response, status, headers, config) {
          console.log('@@@ Error: in retrieving Google Finance stock quote, ticker = ' + symbol);
        });
      };

      getQuote($scope.ticker.tick.name); //Initialize
      $scope.getQuote = getQuote; //as defined above
    }
  ]
);

HTML:

<span>{{stockQuoteData.l}}, {{stockQuoteData.lt}}</span>

В верхней части домашней страницы YouTiming.com я разместил заметки о том, как отключить политику CORS в Chrome и Safari.

1
Daniel C. Deng

При вызове обещания, определенного в сервисе или на фабрике, обязательно используйте сервис, так как я не смог получить ответ от обещания, определенного на фабрике. Вот как я называю обещание, определенное в услуге. 

myApp.service('serverOperations', function($http) {
        this.get_data = function(user) {
          return $http.post('http://localhost/serverOperations.php?action=get_data', user);
        };
})


myApp.controller('loginCtrl', function($http, $q, serverOperations, user) {        
    serverOperations.get_data(user)
        .then( function(response) {
            console.log(response.data);
            }
        );
})
0
Lukáš Černý