【问题标题】:jQuery + JSONP + Yahoo Query LanguagejQuery + JSONP + 雅虎查询语言
【发布时间】:2011-03-08 00:50:20
【问题描述】:

我想从外部来源获取实时汇率,所以我发现了这个很棒的网络服务:

Currency Convertor

这项服务的工作方式非常棒,唯一的缺点是它不提供 JSONP 结果,只提供 XML。因此,我们在尝试使用 jQuery $.ajax() 使用此 Web 服务时遇到了跨浏览器问题。

所以我找到了Yahoo Query Language,它以 JSONP 形式返回结果,并且 mangae 使用其他 Web 服务并将结果返回给我。这也有效,这是一个示例 URL:

http://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20xml%20where%20url%3D'http%3A%2F%2Fwww.webservicex.net%2FCurrencyConvertor.asmx%2FConversionRate%3FFromCurrency%3DNOK%26ToCurrency%3DEUR'&format=json&diagnostics=true&callback=cbfunc

这个 URL 返回 JSONP 结果并且工作起来很神奇,但是当我在我的代码中使用它时出现了问题:

$.ajax({
  type: "GET",
  url: urlToWebservice,
  contentType: "application/json; charset=utf-8",
  dataType: "jsonp",
  success: function(data) {
    $("#status").html("OK: " + data.text);
  },
  error: function(xhr, textStatus, errorThrown) {
    $("#status").html("Unavailable: " + textStatus);
  }
});

当我尝试运行此代码时,什么也没有发生,我可以在我的 Firebug javascript 调试器中看到此错误消息:

cbfunc is not defined

cbfunc 是围绕 JSON 响应的容器的名称,但为什么它说未定义?

编辑:

这是我的新代码,但我仍然得到cbfunc is not defined

$.ajax({
  url: "http://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20xml%20where%20url%3D'http%3A%2F%2Fwww.webservicex.net%2FCurrencyConvertor.asmx%2FConversionRate%3FFromCurrency%3DNOK%26ToCurrency%3DEUR'&format=json&callback=cbfunc",
  dataType: 'jsonp',
  jsonp: 'callback',
  jsonpCallback: 'cbfunc'
});

function cbfunc(data) {
  alert("OK");
}

并且永远不会触发“OK”消息...

【问题讨论】:

  • Doh.. 愚蠢的我,function cbfunc(data) 在另一个函数中,当我把它作为一个单独的函数放在这个函数之外时,它就可以工作了!
  • 为什么显式指定回调为cbfunc 并且当您可以让jQuery 处理事情并在您的success 回调中正常进行时对该函数的存在有硬依赖,就像您对非-JSONP 调用?

标签: javascript jquery json web-services jsonp


【解决方案1】:

你绝对应该试试 jQuery-JSONP:http://code.google.com/p/jquery-jsonp/

简化一切:)

【讨论】:

    【解决方案2】:

    它不工作的原因是因为通过在查询字符串中指定callback=cbfunc 会生成一个类型的 URL:

    http://query.yahooapis.com/...&callback=cbfunc&callback=jsonp1277417828303
    

    删除了所有不感兴趣的部分,但 URL 包含两个 callback 参数。其中一个由 jQuery 管理,另一个则不是。 YQL 只查看第一个 callback 参数并返回包含该参数的响应。

    cbfunc({"query":{...}});
    

    但是,您的脚本中没有名为 cbfunc 的函数,这就是您收到未定义错误的原因。 jQuery 在上面的示例中创建了一个名为 jsonp1277417828303 的隐式函数,而 YQL 的响应应该是:

    jsonp1277417828303({"query":{...}});
    

    让 jQuery 对其采取行动,并将响应返回给您的 success 回调,它永远不会这样做。

    因此,正如@SLaks 建议的那样,从您的 URL 中删除 &callback=cbfunc,或者将其替换为 &callback=? 以让 jQuery 处理事情。

    查看working example

    【讨论】:

      【解决方案3】:

      如果可用,请在对$.ajax 的调用中使用jsonpCallback 参数,例如:

       jsonpCallback: "cbfunc",
      

      它的描述,来自jQuery API docs

      指定 jsonp 请求的回调函数名称。将使用此值代替 jQuery 自动生成的随机名称。

      文档后来继续说:

      最好让 jQuery 生成一个唯一的名称,因为这样可以更轻松地管理请求并提供回调和错误处理。当您想要更好地为 GET 请求启用浏览器缓存时,您可能需要指定回调。

      但是,建议在使用 YQL 时使用这种“首选”行为。正是这种方法不理想的原因可能会使这个答案过于冗长,所以这里有一个链接(来自 YQL 博客),详细说明了 jQuery 首选方法的问题,使用了jsonpCallback 等等:Avoiding rate limits and getting banned in YQL and Pipes: Caching is your friend

      【讨论】:

      • 感谢您的回复,这是一个很棒的博客链接。我阅读了他们写的内容并尝试了他们的 jQuery 示例,但我仍然收到 cbfunc is not defined 消息。我已经编辑了我的帖子以包含我的新代码。
      【解决方案4】:

      您应该让 jQuery 处理回调,方法是将 urlToWebservice 更改为以 callback=? 结尾

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-08-16
        • 1970-01-01
        • 2011-06-27
        • 1970-01-01
        • 2015-06-20
        • 2017-09-03
        相关资源
        最近更新 更多