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.