【问题标题】:parsing JSONP $http.jsonp() response in angular.js在 angularjs 中解析 JSON $http.jsonp() 响应
【发布时间】:2012-08-17 10:56:58
【问题描述】:

我正在使用 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;
    });

如何访问/解析返回的 function-wrapped-JSON?

【问题讨论】:

  • 使用 JSONP,您不会“访问/解析返回的 function-wrapped-JSON”。你的回调被调用;它接收 JSON 数据作为参数。
  • 我尝试过类似
  • (对不起,上面的输入太早了)我的回调在什么时候被调用?一个代码 sn-p 真的很有帮助。在这一点上,我尝试了许多不同的方法,但我很难过。
  • 响应返回时调用回调。你有一个名为jsonp_callback 的函数吗?如果没有,那就是你的问题。
  • 现在我写了一个简单的函数来返回json的第一个元素function jsonp_callback(data) { return data.found; //should be 3 }

标签: javascript angularjs jsonp


【解决方案1】:

更新:从 Angular 1.6 开始

您不能再使用 JSON_CALLBACK 字符串作为占位符 指定回调参数值应该去哪里

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

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

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

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

$sceDelegateProvider.resourceUrlWhitelist

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

$sce.trustAsResourceUrl(url)

success/errordeprecated

$http 旧式 promise 方法 successerror 已被弃用,并将在 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_callback 更改为callback=JSON_CALLBACK,如下所示:

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

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

这样做可以让您不必弄脏全局空间。这在 AngularJS 文档here 中有记录。

更新了 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);
    });

【讨论】:

  • 我的返回一个不同的回调:angular.callbacks._0 我应该如何解决这个问题?
  • @eaon21 你有小提琴的例子吗?
  • @eaon21 这是期望的行为,角度将 JSON_CALLBACK 替换为动态生成的,您不必关注它
  • 例如,你如何调用 Youtube api?
  • 看来他们有自己的客户端库来与 API 交互。你有什么例子可以帮助缩小你想要做的事情吗?
【解决方案2】:

最重要的事情我有一段时间没明白,请求必须包含“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 文件一起使用。
【解决方案3】:

这很有帮助。 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 代码)

    【讨论】:

    • 做到了!事实证明,我搞砸了范围。谢谢!
    • 这个答案不是很有帮助。它不遵循 AngularJS 的范围。
    • @xil3 感谢您的反馈;不幸的是,只有 OP(缩写词)可以切换接受的答案,而不是我。
    • @DanieleBrugnara 请参阅以前的 cmets 来回答这个问题。
    【解决方案5】:

    你还需要在参数中设置callback

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

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

    【讨论】:

      【解决方案6】:

      为了解析做这个-

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

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

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

      {{data}}
      

      【讨论】:

        【解决方案7】:

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

        【讨论】:

          【解决方案8】:

          我使用的是 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);
              });
          

          【讨论】:

            猜你喜欢
            • 2015-02-26
            • 2015-08-27
            • 1970-01-01
            • 2013-07-28
            • 1970-01-01
            • 2013-02-10
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多