analisi della risposta JSONP $ http.jsonp () in angular.js


112

Sto usando la $http.jsonp()richiesta di angular che sta restituendo con successo json avvolto in una funzione:

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

$http.jsonp(url).
    success(function(data, status, headers, config) {
        //what do I do here?
    }).
    error(function(data, status, headers, config) {
        $scope.error = true;
    });

Come accedere / analizzare il JSON restituito dalla funzione?


4
Con JSONP non si "accede / analizza il JSON restituito dalla funzione". Viene chiamata la tua richiamata; riceve i dati JSON come argomento.
Matt Ball

Ho provato a fare qualcosa del tipo
acronimo

(scusa, premi invio troppo presto sopra) A che punto viene chiamata la mia richiamata? Uno snippet di codice sarebbe davvero utile. Ho provato una serie di cose diverse a questo punto e sono perplesso.
akronymn

La richiamata viene chiamata quando la risposta torna. Hai una funzione chiamata jsonp_callback? In caso contrario, c'è il tuo problema.
Matt Ball

per ora ho scritto una semplice funzione per restituire solo il primo elemento del json, function jsonp_callback(data) { return data.found; //should be 3 }
akronymn

Risposte:


300

AGGIORNAMENTO: da Angular 1.6

Non puoi più utilizzare la stringa JSON_CALLBACK come segnaposto per specificare dove deve essere posizionato il valore del parametro callback

Ora devi definire la richiamata in questo modo:

$http.jsonp('some/trusted/url', {jsonpCallbackParam: 'callback'})

Modifica / accedi / dichiara il parametro tramite $http.defaults.jsonpCallbackParam, il valore predefinito ècallback

Nota: devi anche assicurarti che il tuo URL sia aggiunto alla lista attendibile / bianca:

$sceDelegateProvider.resourceUrlWhitelist

o esplicitamente attendibile tramite:

$sce.trustAsResourceUrl(url)

success/errorsono stati deprecati .

I $httpmetodi legacy promise successe errorsono stati deprecati e verranno rimossi nella v1.6.0. Usa invece il metodo standard then. Se $httpProvider.useLegacyPromiseExtensionsè impostato su, falsequesti metodi verranno lanciati $http/legacy error.

USO:

var url = "http://public-api.wordpress.com/rest/v1/sites/wtmpeachtest.wordpress.com/posts"
var trustedUrl = $sce.trustAsResourceUrl(url);

$http.jsonp(trustedUrl, {jsonpCallbackParam: 'callback'})
    .then(function(data){
        console.log(data.found);
    });

Risposta precedente: Angular 1.5.xe precedenti

Tutto quello che dovresti fare è cambiare callback=jsonp_callbackin questo callback=JSON_CALLBACKmodo:

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

E poi la tua .successfunzione dovrebbe attivarsi come hai fatto se il ritorno ha avuto successo.

In questo modo eviti di dover sporcare lo spazio globale. Questo è documentato nella documentazione di AngularJS qui .

Aggiornato il violino di Matt Ball per utilizzare questo metodo: http://jsfiddle.net/subhaze/a4Rc2/114/

Esempio completo:

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

$http.jsonp(url)
    .success(function(data){
        console.log(data.found);
    });

5
il mio sta restituendo una richiamata diversa: angular.callbacks._0 come dovrei risolvere questo problema?
raberana

@ eaon21 hai un esempio di violino?
subhaze

2
@ eaon21 è il comportamento desiderato, angolare sostituisce JSON_CALLBACK con uno generato in modo dinamico, non devi prestargli attenzione
Guillaume86,

E come si chiama l'API di Youtube, ad esempio?
Gino

Sembra che abbiano la propria libreria lato client per interagire con l'API. Hai qualche esempio che può aiutarti a restringere ciò che stai cercando di fare?
subhaze

69

La COSA PIÙ IMPORTANTE che non ho capito per un bel po 'è che la richiesta DEVE contenere "callback = JSON_CALLBACK", perché AngularJS modifica l'URL della richiesta , sostituendo un identificatore univoco per "JSON_CALLBACK". La risposta del server deve utilizzare il valore del parametro "callback" invece dell'hard coding "JSON_CALLBACK":

JSON_CALLBACK(json_response);  // wrong!

Dato che stavo scrivendo il mio script server PHP, pensavo di sapere quale nome di funzione voleva e non avevo bisogno di passare "callback = JSON_CALLBACK" nella richiesta. Grosso errore!

AngularJS sostituisce "JSON_CALLBACK" nella richiesta con un nome di funzione univoco (come "callback = angular.callbacks._0") e la risposta del server deve restituire quel valore:

angular.callbacks._0(json_response);

2
C'è un modo per cambiare il nome del callback in modo che funzioni con jsonfile statici hardcoded.
Pavel Nikolov

9

Questo è stato molto utile. Angular non funziona esattamente come JQuery. Ha il proprio metodo jsonp (), che in effetti richiede "& callback = JSON_CALLBACK" alla fine della stringa di query. Ecco un esempio:

var librivoxSearch = angular.module('librivoxSearch', []);
librivoxSearch.controller('librivoxSearchController', function ($scope, $http) {
    $http.jsonp('http://librivox.org/api/feed/audiobooks/author/Melville?format=jsonp&callback=JSON_CALLBACK').success(function (data) {
        $scope.data = data;
    });
});

Quindi visualizza o manipola {{data}} nel tuo modello Angular.


4

Questo dovrebbe funzionare bene per te, purché la funzione jsonp_callbacksia visibile nell'ambito globale:

function jsonp_callback(data) {
    // returning from async callbacks is (generally) meaningless
    console.log(data.found);
}

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

$http.jsonp(url);

Demo completa: http://jsfiddle.net/mattball/a4Rc2/ (disclaimer: non ho mai scritto alcun codice AngularJS prima)


È stato così! Si scopre l'ambito che stavo incasinando. Grazie!
akronymn

1
Questa risposta non è stata molto utile. Non segue lo scopo di AngularJS.
xil3

1
@ xil3 grazie per il feedback; purtroppo solo l'OP (acronimo) può cambiare la risposta accettata, non io.
Matt Ball

@DanieleBrugnara si prega di vedere i commenti precedenti a questa risposta.
Matt Ball

4

Devi ancora impostare callbacki parametri:

var params = {
  'a': b,
  'token_auth': TOKEN,
  'callback': 'functionName'
};
$sce.trustAsResourceUrl(url);

$http.jsonp(url, {
  params: params
});

Dove 'functionName' è un riferimento in stringa a una funzione definita a livello globale. Puoi definirlo al di fuori del tuo script angolare e quindi ridefinirlo nel tuo modulo.


2

Per l'analisi fai questo-

   $http.jsonp(url).
    success(function(data, status, headers, config) {
    //what do I do here?
     $scope.data=data;
}).

Oppure puoi usare `$ scope.data = JSON.Stringify (data);

Nel modello angolare puoi usarlo come

{{data}}

0

per me le soluzioni di cui sopra hanno funzionato solo una volta che ho aggiunto "format = jsonp" ai parametri della richiesta.


0

Sto usando angolare 1.6.4 e la risposta fornita da subhaze non ha funzionato per me. L'ho modificato un po 'e poi ha funzionato: devi usare il valore restituito da $ sce.trustAsResourceUrl . Codice completo:

var url = "http://public-api.wordpress.com/rest/v1/sites/wtmpeachtest.wordpress.com/posts"
url = $sce.trustAsResourceUrl(url);

$http.jsonp(url, {jsonpCallbackParam: 'callback'})
    .then(function(data){
        console.log(data.found);
    });
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.