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

IT技术 javascript angularjs jsonp
2021-02-02 05:13:54

我正在使用 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?

6个回答

更新:从 Angular 1.6 开始

您不能再使用 JSON_CALLBACK 字符串作为占位符来指定回调参数值的位置

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

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

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

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

$sceDelegateProvider.resourceUrlWhitelist

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

$sce.trustAsResourceUrl(url)

success/error弃用

$http传统方法的Promisesuccess,并error已被弃用,并将在V1.6.0被删除。请改用标准 then 方法。如果$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);
    });
@eaon21 你有小提琴的例子吗?
2021-03-22 05:13:54
我的正在返回一个不同的回调:angular.callbacks._0 我应该如何解决这个问题?
2021-03-28 05:13:54
例如,您如何调用 Youtube api?
2021-03-30 05:13:54
@eaon21 这是你想要的行为,angular 将 JSON_CALLBACK 替换为动态生成的,你不必关注它
2021-04-01 05:13:54
看起来他们有自己的客户端库来与 API 交互。你有什么例子可以帮助缩小你想要做的事情的范围?
2021-04-11 05:13:54

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

JSON_CALLBACK(json_response);  // wrong!

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

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

angular.callbacks._0(json_response);
有什么方法可以更改回调的名称,以便它可以与硬编码的静态json文件一起使用。
2021-03-13 05:13:54

这非常有帮助。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 }}。

只要该函数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 代码)

@DanieleBrugnara 请参阅之前对此答案的评论。
2021-03-22 05:13:54
做到了!原来是我搞砸的范围。谢谢!
2021-04-04 05:13:54
@xil3 感谢您的反馈;不幸的是,只有 OP(缩写词)可以切换已接受的答案,而不是我。
2021-04-04 05:13:54
这个答案不是很有帮助。它不遵循 AngularJS 的范围。
2021-04-05 05:13:54

您仍然需要callback在参数中设置

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

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

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