在angular.js中解析JSONP $ http.jsonp()响应


112

我正在使用angular的$http.jsonp()请求,该请求成功返回包装在函数中的json:

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

如何访问/解析返回的函数包装的JSON?


4
使用JSONP,您无需“访问/解析返回的函数包装的JSON”。您的回调被调用;它接收JSON数据作为参数。
马特·鲍尔

我尝试做类似的事情
akronymn

(很抱歉,上面的输入太早了)我的回调在什么时候被调用?代码段将非常有帮助。在这一点上,我尝试了许多不同的尝试,但感到很困惑。
akronymn 2012年

响应返回时将调用回调。您有一个名为的函数jsonp_callback吗?如果没有,那是你的问题。
马特·鲍尔

现在,我已经编写了一个简单的函数来返回json的第一个元素,即 function jsonp_callback(data) { return data.found; //should be 3 }
akronymn

Answers:


300

更新:自Angular 1.6起

您不能再使用JSON_CALLBACK字符串作为占位符来指定回调参数值应放在何处

您现在必须像这样定义回调:

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

通过更改/访问/声明参数$http.defaults.jsonpCallbackParam,默认为callback

注意:您还必须确保将URL添加到受信任/白名单中:

$sceDelegateProvider.resourceUrlWhitelist

或通过以下方式明确信任:

$sce.trustAsResourceUrl(url)

success/error弃用了

$http传统方法的承诺success,并error已被弃用,并将在V1.6.0被删除。请改用标准然后方法。如果$httpProvider.useLegacyPromiseExtensions设置为,false则这些方法将抛出$http/legacy error

用:

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

上一个答案:Angular 1.5.x及更低版本

您要做的就是更改callback=jsonp_callbackcallback=JSON_CALLBACK这样:

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

然后.success,如果返回成功,则函数应该像您拥有的那样触发。

这样做可以避免您浪费全球空间。这在此处的AngularJS文档中有说明。

更新了Matt Ball的小提琴以使用此方法:http : //jsfiddle.net/subhaze/a4Rc2/114/

完整示例:

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
我的返回一个不同的回调:angular.callbacks._0我该如何解决?
raberana

@ eaon21你有小提琴的例子吗?
2013年

2
@ eaon21这是理想的行为,将JSON_CALLBACK替换为动态生成的行为,您不必注意它
Guillaume86

以及您如何称呼Youtube api?
吉诺

看来它们具有用于与API交互的自己的客户端库。您有任何可以帮助您缩小尝试范围的示例吗?
Subhaze

69

我已经很长时间不了解的最重要的事情是请求必须包含“ callback = JSON_CALLBACK”,因为AngularJS 修改了请求url,用唯一的标识符替换了“ JSON_CALLBACK”。服务器响应必须使用'callback'参数的值,而不是硬编码“ JSON_CALLBACK”:

JSON_CALLBACK(json_response);  // wrong!

自从我编写自己的PHP服务器脚本以来,我以为我知道它想要什么函数名称,并且不需要在请求中传递“ callback = JSON_CALLBACK”。大错!

AngularJS用唯一的函数名称(例如“ callback = angular.callbacks._0”)替换请求中的“ JSON_CALLBACK”,并且服务器响应必须返回该值:

angular.callbacks._0(json_response);

2
有什么方法可以更改回调的名称,以便它与硬编码的静态json文件一起使用。
帕维尔·尼科洛夫

9

这非常有帮助。Angular不能完全像JQuery一样工作。它具有自己的jsonp()方法,该方法的确在查询字符串的末尾需要“&callback = JSON_CALLBACK”。这是一个例子:

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

然后在Angular模板中显示或操作{{data}}。


4

只要该函数jsonp_callback在全局范围内可见,这对您就可以正常工作:

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

完整演示:http : //jsfiddle.net/mattball/a4Rc2/(免责声明:我之前从未写过任何AngularJS代码)


做到了!原来,我的范围很广。谢谢!
akronymn 2012年

1
这个答案不是很有帮助。它不符合AngularJS的范围。
xil3 2013年

1
@ xil3感谢您的反馈;不幸的是,只有OP(akronymn)可以切换接受的答案,而不是我。
马特·鲍尔

@DanieleBrugnara,请参阅此答案的先前评论。
Matt Ball

4

您仍然需要设置callback参数:

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

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

其中“ functionName”是对全局定义函数的字符串化引用。您可以在角度脚本之外定义它,然后在模块中重新定义它。


2

对于解析,请执行以下操作-

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

或者您可以使用$ scope.data = JSON.Stringify(data);

在Angular模板中,您可以将其用作

{{data}}

0

对我来说,上述解决方案仅在我将“ format = jsonp”添加到请求参数后才有效。


0

我使用的是angular 1.6.4,subhaze提供的答案对我不起作用。我对其进行了一些修改,然后才起作用-您必须使用$ sce.trustAsResourceUrl返回的值。完整代码:

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);
    });
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.