Yelp API、OAuth和Angular与JSONP只工作一次



所以这个问题已经被问了好几次了,但我相信我终于把问题归结为问题所在。我在Angular中使用Yelp API,它需要OAuth 1.0a才能访问。像大多数做这种实现的人一样,我使用以下代码:

.factory('YelpApi', ['$http',
      function ($http) {
        var randomString = function (length, chars) {
          var result = '';
          for (var i = length; i > 0; --i) {
            result += chars[Math.round(Math.random() * (chars.length - 1))];
          }
          return result;
        };
        var retrieveYelp = function (name, callback) {
          var method =  'GET';
          var url =     'http://api.yelp.com/v2/search';
          var params = {
            callback:                 'angular.callbacks._0',
            ll:                       /* hidden */,
            radius_filter:            '3219',
            oauth_consumer_key:       /* hidden */, // consumer key
            oauth_token:              /* hidden */, //Token
            oauth_signature_method:   'HMAC-SHA1',
            oauth_timestamp:          new Date().getTime(),
            oauth_nonce:              randomString(32, '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'),
            term:                     name || 'food', 
            actionlinks:              true
          }; // end params
          var consumerSecret =        /* hidden */; //Consumer Secret
          var tokenSecret =           /* hidden */; //Token Secret
          var signature = 
            oauthSignature.generate(
              method, 
              url, 
              params, 
              consumerSecret, 
              tokenSecret, 
              { encodeSignature: false }
            ); 
            // end signature
          params['oauth_signature'] = signature;
          console.log('inside yelpapi factory');
          console.log('Term searched for: ' + params.term);
          $http.jsonp(url, { params : params })
            .then(callback, function(err) {
              console.log('An error occured: ', err);
            });
            console.log("inside end of yelpapi factory");
        }; // end retrieveYelp
        return {
          retrieveYelp: retrieveYelp      
        };
      } // end function
    ]) // end factory

问题是:

使用'angular.callbacks._0'作为回调使其第一次工作,因为它强制它使用第一个回调,但会中断后续请求。实际上,您应该使用JSON_CALLBACK来适当地增加回调,但这会破坏一切。Yelp生成的错误是"无效签名"。我认为这是由于Angular直到之后的才替换JSON_CALLBACK,从而导致预期签名与实际签名不同。我正在使用这个签名生成器。

如何绕过这一点,确保Angular在确保正确生成签名的同时正确增加回调

我找到了一种丑陋的方法来解决这个问题。在下面的文章中,有一个关于如何创建自己的拦截器来增加jsonp回调参数(angular.callbacks._0,angular.cacallbacks._1等)的描述

如何自定义angularjs-jsonp回调名称?

这种一对一的解决方案在我的情况下不起作用。对于必须创建oauth签名的yelp和查询,param回调应该分别包含在签名中,然后在执行jsonp请求之前应该已经递增。

因此,在我的服务中,在进行签名和jsonp请求之前,我只调用计数器来生成新的增量。

在您的情况下,我建议更改您的代码如下:

var retrieveYelp = function (name, callback) {
// GENERATE increment and use it in the params
var callbackId = angular.callbacks.counter.toString(36);
      var method =  'GET';
      var url =     'http://api.yelp.com/v2/search';
      var params = {
        callback:                 'angular.callbacks._' + callbackId,
        ll:                       /* hidden */,
        radius_filter:            '3219',
        oauth_consumer_key:       /* hidden */, // consumer key
        oauth_token:              /* hidden */, //Token
        oauth_signature_method:   'HMAC-SHA1',
        oauth_timestamp:          new Date().getTime(),
        oauth_nonce:              randomString(32, '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'),
        term:                     name || 'food', 
        actionlinks:              true
      };

我同意,我发现这个解决方案并不是超级愚蠢,但至少它有效,而且似乎没有副作用。

最新更新