2

我正在尝试将骨干用于本地项目,该项目永远不会看到真正的 Web 服务器,并且通过 AJAX 与 Yelp API 交互。Yelp API 要求我们使用 oauth 进行身份验证,并提供了示例代码,我根据这些代码对自己的代码进行了建模。当我使用示例代码时,我没有遇到任何跨域问题或任何问题。但是,当我关闭浏览器安全选项时,我只会收到 400 错误响应。

我曾尝试按如下方式覆盖 fetch 方法:

fetch: function(options) {
  var accessor, message, parameterMap, parameters;
  if (!options) {
    options = {};
  }
  accessor = {
    consumerSecret: LOAF.auth.conserumerSecret,
    tokenSecret: LOAF.auth.accessTokenSecret
  };
  parameters = [];
  parameters.push(['oauth_consumer_key', LOAF.auth.consumerKey]);
  parameters.push(['oauth_consumer_secret', LOAF.auth.consumerSecret]);
  parameters.push(['oauth_token', LOAF.auth.accessToken]);
  parameters.push(['oauth_signature_method', 'HMAC-SHA1']);
  parameters.push(['location', "New York City"]);
  message = {
    'action': this.url,
    'method': 'GET',
    'parameters': parameters
  };
  OAuth.setTimestampAndNonce(message);
  OAuth.SignatureMethod.sign(message, accessor);
  parameterMap = OAuth.getParameterMap(message.parameters);
  parameterMap.oauth_signature = OAuth.percentEncode(parameterMap.oauth_signature);
  options.url = this.url;
  options.data = parameterMap;
  options.cache = true;
  options.dataType = 'json';
  options.success = this.onResponse;
  console.log("Attempting");
  console.log(options);
  return Backbone.Model.prototype.fetch.apply(this, options);
},

但这会产生 400 响应。我有一种感觉,因为我没有正确地进行 AJAX 调用,因为主干为我完成了大部分工作,并且可能会覆盖我正在设置的一些选项。我认为我需要做的是覆盖这个集合的“同步”方法,而不是只处理 OAuth 并自己解析响应。有一个更好的方法吗?

4

1 回答 1

1

我不确定这是否是正确的做事方式,但它是这样工作的,所以这是我的解决方案。我覆盖了 fetch 并且从不调用默认的 fetch 方法。相反,我在 fetch 方法中进行了 ajax 调用,并有一个onResponse处理响应的方法,为响应创建模型(Yelp Businesses)。希望这可以帮助任何处于相同位置的人。

LOAF.YelpList = Backbone.Collection.extend({
  model: LOAF.Business,
  url: 'http://api.yelp.com/v2/search?',
  fetch: function(options) {
    var accessor, message, parameterMap, parameters;
    if (!options) {
      options = {};
    }
    accessor = {
      consumerSecret: LOAF.auth.consumerSecret,
      tokenSecret: LOAF.auth.accessTokenSecret
    };
    parameters = [];
    parameters.push(['callback', 'cb']);
    parameters.push(['oauth_consumer_key', LOAF.auth.consumerKey]);
    parameters.push(['oauth_consumer_secret', LOAF.auth.consumerSecret]);
    parameters.push(['oauth_token', LOAF.auth.accessToken]);
    parameters.push(['oauth_signature_method', 'HMAC-SHA1']);
    parameters.push(['location', "New York City"]);
    message = {
      'action': this.url,
      'method': 'GET',
      'parameters': parameters
    };
    OAuth.setTimestampAndNonce(message);
    OAuth.SignatureMethod.sign(message, accessor);
    parameterMap = OAuth.getParameterMap(message.parameters);
    parameterMap.oauth_signature = OAuth.percentEncode(parameterMap.oauth_signature);
    options.url = this.url;
    options.data = parameterMap;
    options.cache = true;
    options.dataType = 'jsonp';
    options.jsonpCallback = 'cb';
    options.success = this._onResponse;
    options.context = this;
    return $.ajax(options);
  },
  _onResponse: function(data, textStats, xhr) {
    debugger;
    var _this = this;
    return _.each(data.businesses, function(business) {
      var busModel;
      if (!_this.get(business.id)) {
        busModel = new LOAF.Business(business);
        return _this.add(busModel);
      }
    });
  }
});

有两点需要注意:

  1. 初始代码本来可以工作,但 consumerSecret 拼写错误,导致 OAuth 调用不正确。这就是为什么我收到 400 错误。
  2. 即使你解决了这个问题,也存在跨域调用的问题。切换到我使用的 AJAX 方法可以缓解这个问题。但是,可能存在一种方法来修复这个更原生于 Backbone 的问题。在我的项目的时间范围内,这是行不通的。
于 2012-12-03T09:16:58.567 回答