如何正确使用AngularJS中的HTTP.GET? 具体而言,对于外部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有关的问题。 你能指点一下正确的方式来打这个电话吗? 非常感谢!
首先,你的success()
处理程序只是返回数据,但是这不会返回给getData()
的调用者,因为它已经在callback中了。 $http
是一个返回$promise
的asynchronous调用,所以你必须在数据可用的时候注册一个callback函数。
我build议在AngularJS中查找Promises和$ q库 ,因为它们是传递服务间asynchronous调用的最佳方式。
为了简单起见,下面是您的代码与调用控制器提供的函数callback重写:
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; }); });
最后,还有更好的方法来configuration$http
服务来为你使用config()
来设置$httpProvider
。 检查$ http文档的例子。
我build议你使用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的强大function,如果你想避免嵌套callback,这是非常方便的。
没有必要用$ 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; }); });
尝试这个
myApp.config(['$httpProvider', function($httpProvider) { $httpProvider.defaults.useXDomain = true; delete $httpProvider.defaults.headers.common['X-Requested-With']; } ]);
只要设置useXDomain = true是不够的。 AJAX请求也发送与X-Requested-With头,这表明他们是AJAX。 删除头是必要的,所以服务器不拒绝传入的请求。
所以你需要使用我们所说的诺言。 阅读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]) }())
以Google财经为例,检索股票的最近收盘价和更新的date和时间。 您可以访问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首页的顶部,我已经放置了关于如何在Chrome和Safari上禁用CORS策略的注释。
当调用在服务或工厂中定义的承诺时,请务必使用服务,因为我无法从工厂中定义的承诺获得响应。 这就是我所说的在服务中定义的承诺。
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); } ); })