Come utilizzare HTTP.GET in AngularJS correttamente? In particolare, per una chiamata API esterna?

Ho il seguente codice nel 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(); }); 

Ma, penso che probabilmente sto facendo un errore con il problema relativo al CORS. Potete indicarmi il modo corretto per effettuare questa chiamata? Grazie mille!

Innanzitutto, il tuo gestore di success() restituisce solo i dati, ma non viene restituito al chiamante di getData() poiché è già in un callback. $http è una chiamata asincrona che restituisce un $promise , quindi devi registrare un callback per quando i dati sono disponibili.

Ti consiglio di cercare Promises e la libreria $ q in AngularJS poiché rappresentano il modo migliore per passare le chiamate asincrone tra i servizi.

Per semplicità, ecco il tuo stesso codice riscritto con una funzione di callback fornita dal controller chiamante:

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

Ora, $http restituisce già una promise $, quindi può essere riscritta:

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

Infine, ci sono modi migliori per configurare il servizio $http per gestire le intestazioni per te usando config() per configurare $httpProvider . Scopri la documentazione $ http per gli esempi.

Ti suggerisco di usare 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; } }); 

quindi nel tuo controller puoi usare il metodo

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

le promesse sono potenti funzionalità di angularjs ed è conveniente specialmente se si vuole evitare di annidare i callback.

Non c’è bisogno di promettere con $ http, lo uso solo con due resi:

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

Nel controller

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

Prova questo

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

Basta impostare useXDomain = true non è abbastanza. Anche le richieste AJAX vengono inviate con l’intestazione X-Requested-With, che le indica come AJAX. La rimozione dell’intestazione è necessaria, quindi il server non rifiuta la richiesta in entrata.

Quindi è necessario utilizzare ciò che chiamiamo promise. Leggi come lo gestisce angolarmente qui, https://docs.angularjs.org/api/ng/service/ $ q. Trasforma il nostro supporto $ http in promesse intrinseche così nel tuo caso faremo qualcosa del genere,

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

Come esempio di utilizzo di Google Finance per recuperare l’ultimo prezzo di chiusura del ticker e la data e l’ora aggiornate. È ansible visitare YouTiming.com per l’esecuzione in fase di esecuzione.

Il servizio:

 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 }; } ] ); 

Il controller:

 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 } ] ); 

L'HTML:

 {{stockQuoteData.l}}, {{stockQuoteData.lt}} 

Nella parte superiore della home page di YouTiming.com, ho inserito le note su come disabilitare i criteri CORS su Chrome e Safari.

Quando si chiama una promise definita in un servizio o in una fabbrica, assicurarsi di utilizzare il servizio in quanto non è ansible ottenere una risposta da una promise definita in una fabbrica. È così che chiamo una promise definita in un servizio.

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