analyse de la réponse JSONP $ http.jsonp () dans angular.js

112

J'utilise la $http.jsonp()requête d'angular qui renvoie avec succès json enveloppé dans une fonction:

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

Comment accéder / analyser le JSON-wrapped-function retourné?

akronymn
la source
4
Avec JSONP, vous n'accédez pas / ne analysez pas le JSON encapsulé par fonction renvoyé. Votre rappel est appelé; il reçoit les données JSON en tant qu'argument.
Matt Ball
J'ai essayé de faire quelque chose comme
akronymn
(désolé, appuyez sur Entrée trop tôt) À quel moment mon rappel est-il appelé? Un extrait de code serait vraiment utile. J'ai essayé un certain nombre de choses différentes à ce stade et je suis perplexe.
akronymn
Le rappel est appelé lorsque la réponse revient. Avez-vous une fonction nommée jsonp_callback? Sinon, c'est votre problème.
Matt Ball
pour l'instant, j'ai écrit une fonction simple pour retourner simplement le premier élément du json, function jsonp_callback(data) { return data.found; //should be 3 }
akronymn

Réponses:

300

MISE À JOUR: depuis Angular 1.6

Vous ne pouvez plus utiliser la chaîne JSON_CALLBACK comme espace réservé pour spécifier où la valeur du paramètre de rappel doit aller

Vous devez maintenant définir le rappel comme ceci:

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

Changer / accéder / déclarer le paramètre via $http.defaults.jsonpCallbackParam, la valeur par défaut estcallback

Remarque: vous devez également vous assurer que votre URL est ajoutée à la liste approuvée / blanche:

$sceDelegateProvider.resourceUrlWhitelist

ou explicitement approuvé via:

$sce.trustAsResourceUrl(url)

success/errorétaient obsolètes .

Les $httpméthodes de promesse existantes successet erroront été désapprouvés et seront supprimés dans v1.6.0. Utilisez plutôt la méthode standard alors. Si $httpProvider.useLegacyPromiseExtensionsest défini sur falsealors ces méthodes lanceront $http/legacy error.

UTILISATION:

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

Réponse précédente: Angular 1.5.x et avant

Tout ce que vous devriez faire est de changer callback=jsonp_callbackpour callback=JSON_CALLBACKainsi:

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

Et puis votre .successfonction devrait se déclencher comme vous l'avez si le retour a réussi.

Cela vous évite d'avoir à salir l'espace mondial. Ceci est documenté dans la documentation AngularJS ici .

Mise à jour du violon de Matt Ball pour utiliser cette méthode: http://jsfiddle.net/subhaze/a4Rc2/114/

Exemple complet:

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);
    });
brouiller
la source
5
le mien renvoie un rappel différent: angular.callbacks._0 comment dois-je résoudre ce problème?
raberana
@ eaon21 avez-vous un exemple de violon?
subhaze le
2
@ eaon21 c'est le comportement souhaité, angulaire remplace JSON_CALLBACK par un comportement généré dynamiquement, vous n'avez pas à y prêter attention
Guillaume86
Et comment appelle-t-on l'API Youtube par exemple?
Gino
Il semble qu'ils ont leur propre bibliothèque côté client pour interagir avec l'API. Avez-vous des exemples qui peuvent vous aider à préciser ce que vous essayez de faire?
subhaze
69

La CHOSE LA PLUS IMPORTANTE que je n'ai pas comprise pendant un certain temps est que la requête DOIT contenir "callback = JSON_CALLBACK", car AngularJS modifie l'url de la requête , en remplaçant un identifiant unique par "JSON_CALLBACK". La réponse du serveur doit utiliser la valeur du paramètre 'callback' au lieu du codage en dur "JSON_CALLBACK":

JSON_CALLBACK(json_response);  // wrong!

Depuis que j'écrivais mon propre script de serveur PHP, je pensais savoir quel nom de fonction il voulait et je n'avais pas besoin de passer "callback = JSON_CALLBACK" dans la requête. Grosse erreur!

AngularJS remplace "JSON_CALLBACK" dans la requête par un nom de fonction unique (comme "callback = angular.callbacks._0"), et la réponse du serveur doit renvoyer cette valeur:

angular.callbacks._0(json_response);
Joseph Oster
la source
2
Existe-t-il un moyen de changer le nom du rappel afin qu'il fonctionne avec un jsonfichier statique codé en dur .
Pavel Nikolov
9

Cela a été très utile. Angular ne fonctionne pas exactement comme JQuery. Il a sa propre méthode jsonp (), qui nécessite en effet "& callback = JSON_CALLBACK" à la fin de la chaîne de requête. Voici un exemple:

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

Ensuite, affichez ou manipulez {{data}} dans votre modèle angulaire.

Peter
la source
4

Cela devrait fonctionner parfaitement pour vous, tant que la fonction jsonp_callbackest visible dans la portée 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);

Démo complète: http://jsfiddle.net/mattball/a4Rc2/ (avertissement: je n'ai jamais écrit de code AngularJS auparavant)

Matt Ball
la source
Cela l'a fait! Il s'avère que la portée que je gâchais. Je vous remercie!
akronymn
1
Cette réponse n'a pas été très utile. Il ne suit pas la portée d'AngularJS.
xil3
1
@ xil3 merci pour les commentaires; malheureusement, seul l'OP (akronymn) peut changer la réponse acceptée, pas moi.
Matt Ball
@DanieleBrugnara s'il vous plaît voir les commentaires précédents à cette réponse.
Matt Ball
4

Vous devez encore définir callbackdans les paramètres:

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

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

Où 'functionName' est une référence stringifiée à une fonction définie globalement. Vous pouvez le définir en dehors de votre script angulaire puis le redéfinir dans votre module.

paradis
la source
2

Pour l'analyse, faites ceci-

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

Ou vous pouvez utiliser `$ scope.data = JSON.Stringify (data);

Dans le modèle angulaire, vous pouvez l'utiliser comme

{{data}}
kapil
la source
0

pour moi, les solutions ci-dessus n'ont fonctionné qu'une fois que j'ai ajouté "format = jsonp" aux paramètres de la requête.

Tali
la source
0

J'utilise angular 1.6.4 et la réponse fournie par subhaze n'a pas fonctionné pour moi. Je l'ai un peu modifié, puis cela a fonctionné - vous devez utiliser la valeur renvoyée par $ sce.trustAsResourceUrl . Code complet:

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);
    });
Mikatuo
la source