jQuery + JSONP + 雅虎查询语言
Posted
技术标签:
【中文标题】jQuery + JSONP + 雅虎查询语言【英文标题】:jQuery + JSONP + Yahoo Query Language 【发布时间】: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 调用?
【参考方案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=?
结尾
【讨论】:
以上是关于jQuery + JSONP + 雅虎查询语言的主要内容,如果未能解决你的问题,请参考以下文章