JSONP $ http.jsonp () yanıtını angular.js'de ayrıştırma


112

$http.jsonp()Angular'ın bir işleve sarılmış json'u başarıyla döndüren isteğini kullanıyorum :

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

Döndürülen function-wrapped-JSON'a nasıl erişilir / ayrıştırılır?


4
JSONP ile "döndürülen işlev sarmalanmış JSON'a erişemez / ayrıştırmazsınız." Geri aramanız aranır; JSON verilerini bağımsız değişken olarak alır.
Matt Ball

Gibi bir şey yapmayı denedim
akronymn

(üzgünüm, yukarıya çok erken girin) Geri aramam ne zaman aranıyor? Bir kod parçacığı gerçekten yardımcı olacaktır. Bu noktada birçok farklı şey denedim ve şaşkına döndüm.
akronymn

Geri arama, yanıt geri geldiğinde çağrılır. İsimli bir fonksiyonunuz var jsonp_callbackmı? Değilse, sorunun var.
Matt Ball

şimdilik sadece function jsonp_callback(data) { return data.found; //should be 3 }
json'un

Yanıtlar:


300

GÜNCELLEME: Angular 1.6'dan beri

Artık JSON_CALLBACK dizesini, geri çağrı parametresi değerinin nereye gitmesi gerektiğini belirtmek için bir yer tutucu olarak kullanamazsınız

Şimdi geri aramayı şu şekilde tanımlamalısınız:

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

Değiştir / erişim / beyan et parametresi $http.defaults.jsonpCallbackParam, varsayılan olarakcallback

Not: Ayrıca, URL'nizin güvenilenler / beyaz listeye eklendiğinden emin olmalısınız:

$sceDelegateProvider.resourceUrlWhitelist

veya şu yolla açıkça güvenildi:

$sce.trustAsResourceUrl(url)

success/erroredildi kullanımdan kaldırıldı .

$httpEski vaadi yöntemleri successve erroronaylanmaz ve GO v1.6.0 kaldırılacaktır. Bunun yerine standartı ve ardından yöntemi kullanın. Olarak $httpProvider.useLegacyPromiseExtensionsayarlanırsa, falsebu yöntemler atacaktır $http/legacy error.

KULLANIM:

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

Önceki Cevap: Açısal 1.5.x ve öncesi

Tek yapmanız gereken gereken tüm değişimdir callback=jsonp_callbackiçin callback=JSON_CALLBACKşöyle:

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

Ve sonra .successgeri dönüş başarılı olduysa , işleviniz de sahip olduğunuz gibi çalışacaktır.

Bunu bu şekilde yapmak sizi küresel alanı kirletmekten alıkoyar. Bu angularjs belgelerinde belgelenmiştir burada .

Bu yöntemi kullanmak için Matt Ball'un keman güncellendi: http://jsfiddle.net/subhaze/a4Rc2/114/

Tam örnek:

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
benimki farklı bir geri arama döndürüyor: angular.callbacks._0 bunu nasıl düzeltmeliyim?
raberana

@ eaon21 bir keman örneğiniz var mı?
2013

2
@ eaon21 bu istenen davranış, JSON_CALLBACK'i dinamik olarak oluşturulmuş bir davranışla değiştiriyor, buna dikkat etmeniz gerekmiyor
Guillaume86

Ve mesela Youtube api'yi nasıl çağırırsınız?
Gino

API ile etkileşim için kendi istemci tarafı kütüphanelerine sahip oldukları görülüyor. Yapmaya çalıştığınız şeyi daraltmanıza yardımcı olabilecek herhangi bir örnek var mı?
subhaze

69

Bir süredir anlamadığım EN ÖNEMLİ ŞEY , isteğin "callback = JSON_CALLBACK" içermesi GEREKİR çünkü AngularJS istek url'sini değiştirerek "JSON_CALLBACK" yerine benzersiz bir tanımlayıcı koyar. Sunucu yanıtı, "JSON_CALLBACK" sabit kodlaması yerine "geri çağrı" parametresinin değerini kullanmalıdır:

JSON_CALLBACK(json_response);  // wrong!

Kendi PHP sunucu betiğimi yazdığım için, hangi işlev adını istediğini bildiğimi ve istekte "callback = JSON_CALLBACK" geçmesine gerek olmadığını düşündüm. Büyük hata!

AngularJS, istekteki "JSON_CALLBACK" ifadesini benzersiz bir işlev adıyla ("callback = angular.callbacks._0" gibi) değiştirir ve sunucu yanıtı bu değeri döndürmelidir:

angular.callbacks._0(json_response);

2
Geri aramanın adını sabit kodlanmış statik jsondosyayla çalışacak şekilde değiştirebilmemizin bir yolu var mı ?
Pavel Nikolov

9

Bu çok yardımcı oldu. Angular tam olarak JQuery gibi çalışmaz. Sorgu dizesinin sonunda gerçekten "& callback = JSON_CALLBACK" gerektiren kendi jsonp () yöntemine sahiptir. İşte bir örnek:

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

Ardından, Angular şablonunuzda {{data}} öğesini görüntüleyin veya değiştirin.


4

İşlev jsonp_callbackgenel kapsamda göründüğü sürece bu sizin için gayet iyi çalışmalıdır :

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

Tam demo: http://jsfiddle.net/mattball/a4Rc2/ (sorumluluk reddi: Daha önce hiç AngularJS kodu yazmadım)


Başardı! Ortalığı karıştırdığım kapsam ortaya çıktı. Teşekkür ederim!
akronymn

1
Bu cevap pek yardımcı olmadı. AngularJS kapsamına uymuyor.
xil3

1
@ xil3 geri bildirim için teşekkürler; ne yazık ki sadece OP (akronim) kabul edilen cevabı değiştirebilir, ben değil.
Matt Ball

@DanieleBrugnara lütfen bu cevaba ilişkin önceki yorumlara bakın.
Matt Ball

4

Yine callbackde parametreleri ayarlamanız gerekir :

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

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

Burada 'işlevAdı', küresel olarak tanımlanmış işleve dizgisel bir referanstır. Bunu açısal betiğinizin dışında tanımlayabilir ve ardından modülünüzde yeniden tanımlayabilirsiniz.


2

Ayrıştırmak için bunu yapın-

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

Veya `$ kapsam.data = JSON.Stringify (data);

Açısal şablonda bunu şu şekilde kullanabilirsiniz:

{{data}}

0

benim için yukarıdaki çözümler yalnızca istek parametrelerine "format = jsonp" ekledikten sonra çalıştı.


0

1.6.4 açısal kullanıyorum ve subhaze tarafından sağlanan cevap benim için işe yaramadı. Biraz değiştirdim ve sonra çalıştı - $ sce.trustAsResourceUrl tarafından döndürülen değeri kullanmanız gerekiyor . Tam kod:

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);
    });
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.