analizar la respuesta JSONP $ http.jsonp () en angular.js

112

Estoy usando la $http.jsonp()solicitud de angular que devuelve json correctamente envuelto en una función:

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

¿Cómo acceder / analizar la función devuelta-envuelto-JSON?

Akronymn
fuente
4
Con JSONP no "accede / analiza la función devuelta en formato JSON". Se llama a su devolución de llamada; recibe los datos JSON como argumento.
Matt Ball
Intenté hacer algo como
akronymn
(lo siento, presione enter demasiado pronto arriba) ¿En qué momento se llama a mi devolución de llamada? Un fragmento de código sería realmente útil. He intentado varias cosas diferentes en este momento y estoy perplejo.
akronymn
Se llama a la devolución de llamada cuando vuelve la respuesta. ¿Tiene una función nombrada jsonp_callback? Si no, ese es tu problema.
Matt Ball
por ahora, he escrito una función simple para devolver el primer elemento del json, function jsonp_callback(data) { return data.found; //should be 3 }
akronymn

Respuestas:

300

ACTUALIZACIÓN: desde Angular 1.6

Ya no puede usar la cadena JSON_CALLBACK como marcador de posición para especificar dónde debe ir el valor del parámetro de devolución de llamada

Ahora debe definir la devolución de llamada así:

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

Cambiar / acceder / declarar $http.defaults.jsonpCallbackParamparámetro a través de , por defecto escallback

Nota: También debe asegurarse de que su URL se agregue a la lista blanca / confiable:

$sceDelegateProvider.resourceUrlWhitelist

o de confianza explícita a través de:

$sce.trustAsResourceUrl(url)

success/errorestaban en desuso .

Los $httpmétodos heredados de la promesa successy errorhan quedado obsoletos y se retiró en v1.6.0. En su lugar, utilice el método estándar y luego. Si $httpProvider.useLegacyPromiseExtensionsse establece en false, estos métodos arrojarán $http/legacy error.

UTILIZAR:

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

Respuesta anterior: Angular 1.5.xy antes

Todo lo que debe hacer es cambiar callback=jsonp_callbacka Me callback=JSON_CALLBACKgusta:

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

Y luego su .successfunción debería dispararse como lo hizo si el retorno fue exitoso.

Hacerlo de esta manera evita que tengas que ensuciar el espacio global. Esto está documentado en la documentación de AngularJS aquí .

Se actualizó el violín de Matt Ball para usar este método: http://jsfiddle.net/subhaze/a4Rc2/114/

Ejemplo 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);
    });
calmar
fuente
5
el mío está devolviendo una devolución de llamada diferente: angular.callbacks._0 ¿cómo debo solucionar esto?
raberana
@ eaon21 ¿tienes un ejemplo de violín?
subhaze
2
@ eaon21 es el comportamiento deseado, angular sustituye JSON_CALLBACK a uno generado dinámicamente, no tiene que prestarle atención
Guillaume86
¿Y cómo se llama la API de Youtube, por ejemplo?
Gino
Parece que tienen su propia biblioteca del lado del cliente para interactuar con la API. ¿Algún ejemplo que tenga que pueda ayudar a delimitar lo que está tratando de hacer?
subhaze
69

Lo MÁS IMPORTANTE que no entendí por un tiempo es que la solicitud DEBE contener "callback = JSON_CALLBACK", porque AngularJS modifica la URL de la solicitud , sustituyendo un identificador único por "JSON_CALLBACK". La respuesta del servidor debe usar el valor del parámetro 'callback' en lugar de la codificación "JSON_CALLBACK":

JSON_CALLBACK(json_response);  // wrong!

Como estaba escribiendo mi propio script de servidor PHP, pensé que sabía qué nombre de función quería y no necesitaba pasar "callback = JSON_CALLBACK" en la solicitud. ¡Gran error!

AngularJS reemplaza "JSON_CALLBACK" en la solicitud con un nombre de función único (como "callback = angular.callbacks._0"), y la respuesta del servidor debe devolver ese valor:

angular.callbacks._0(json_response);
Joseph Oster
fuente
2
¿Hay alguna forma en que podamos cambiar el nombre de la devolución de llamada para que funcione con un jsonarchivo estático codificado ?
Pavel Nikolov
9

Esto fue muy útil. Angular no funciona exactamente como JQuery. Tiene su propio método jsonp (), que de hecho requiere "& callback = JSON_CALLBACK" al final de la cadena de consulta. He aquí un ejemplo:

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

Luego muestre o manipule {{data}} en su plantilla Angular.

Pedro
fuente
4

Esto debería funcionar bien para usted, siempre que la función jsonp_callbacksea ​​visible en el alcance global:

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

Demostración completa: http://jsfiddle.net/mattball/a4Rc2/ (descargo de responsabilidad: nunca antes había escrito ningún código AngularJS)

Matt Ball
fuente
¡Eso fue todo! Resulta que el alcance que estaba arruinando. ¡Gracias!
Akronymn
1
Esta respuesta no fue de mucha ayuda. No sigue el alcance de AngularJS.
xil3
1
@ xil3 gracias por los comentarios; desafortunadamente, solo el OP (akronymn) puede cambiar la respuesta aceptada, no yo.
Matt Ball
@DanieleBrugnara, consulte los comentarios anteriores a esta respuesta.
Matt Ball
4

Todavía necesitas configurar callbacklos parámetros:

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

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

Donde 'functionName' es una referencia en cadena a una función definida globalmente. Puede definirlo fuera de su script angular y luego redefinirlo en su módulo.

paradita
fuente
2

Para analizar haz esto-

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

O puede usar `$ scope.data = JSON.Stringify (data);

En la plantilla angular puedes usarla como

{{data}}
kapil
fuente
0

para mí, las soluciones anteriores funcionaron solo una vez que agregué "format = jsonp" a los parámetros de solicitud.

Tali
fuente
0

Estoy usando angular 1.6.4 y la respuesta proporcionada por subhaze no funcionó para mí. Lo modifiqué un poco y luego funcionó: debe usar el valor devuelto por $ sce.trustAsResourceUrl . Código 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);
    });
mikatuo
fuente