使用 JSONP、jQuery 和 Yahoo! 查询语言构建 mashup

JSONP 是一种有效的跨域通信技术,允许您绕过当前浏览器带来的同源策略限制。上一篇json和jsonp为您展示了如何利用 jQeury 的本地 JSONP 支持,从称为 JSONP 服务的第三方服务收集 JSON 格式的内容。这篇文章将介绍 Yahoo! 查询语言(YQL),这种单端点的 JSONP 服务允许您查询、过滤和合并来自不同数据源的数据。此外,本文还会为您介绍如何构建一个 mashup 应用程序的 jQuery 实现,该应用程序可收集股票报价、纽约时报 RSS 提要和气象预报数据,并将其显示在一个 Web 页面中。

将 Web 作为数据库

Web 上有许多结构化数据,通过多种多样的 Web 服务或 API 公开给开发人员。这些服务需要您进行访问和查询,随后以非标准化的方式解析结果。每种服务都有自己的访问 URL 以及描述如何查询和理解结果的文档。可将 YQL 视为一种标准的方法,查询由不同 URL 的不同服务提供的数据。YQL 提供了单端点服务,允许您在 Web 上过滤和合并数据,而不必处理各种服务的特质。

YQL 基本上就是一种基于 SQL 的查询语言,允许以标准的方式从多个服务中查询和检索结构化数据。但 YQL 也是一种由 Yahoo! 托管的查询引擎,在 REST 端点公开。YQL 使用人们熟悉的表格与行的关系数据库模型。但数据在内部是以 XML 的形式解释和结构化的。如果底层数据源未提供 XML 数据,YQL 会进行转换。它以 XML 或 JSON 的形式返回响应(您可在调用服务时指定)。此外,如果您向服务请求 JSON 数据,还可指定回调函数。这使 YQL 服务成为了一种 JSONP 服务,最重要的是:它为众多 Web 服务引入了自动化 JSONP 支持。

YQL 可理解和支持的数据源包括:RSS、Atom、JSON、XML、CSV、HTML、Flickr、Yahoo! Finance、Weather 等。由于 YQL 也支持外部数据源(Yahoo! 以外的数据源),因而就有了构建 mashup 应用程序的无限种可能性。可以说,它在单独一个界面内将 Web 与您的应用程序相连。

图 1. YQL 作为仲裁服务


上文已经提到过,YQL 是一种类似于 SQL 的语言,可在 Web 中查询结构化数据。因此,SELECT 是 YQL 语句中的主要动词。其语法也与 SQL 极为相似:

SELECT fields FROM source_table WHERE filter ..

下面的示例展示了一个简单的查询,从纽约时报 RSS 提要检索标题:

select title from rss where url="http://www.nytimes.com/services/xml/rss/nyt/HomePage.xml"

下面是一个更具体的 YQL 示例,检索纽约的素食餐馆,将数量限制为 3 家:

select Title,Address,City,Rating.AverageRating from local.search 
where query="vegetarian" and location="New York,NY" limit 3
上面的查询会返回类似于示例 1 的 JSON 响应(忽略所返回的关于查询的元数据)。

示例1. JSON 查询响应

"results": {
  "Result": [
    {
      "Title": "World of Vegetarian Incorporated","Address": "24 Pell St","City": "New York","Rating": {
        "AverageRating": "5"
      }
    },{
      "Title": "Counter","Address": "105 1st Ave","Rating": {
        "AverageRating": "4"
      }
    },{
      "Title": "Red Bamboo","Address": "140 W 4th St","Rating": {
        "AverageRating": "4.5"
      }
    }
  ]
}

甚至可通过 YQL 查询 Web:

select title,abstract,url from search.web where query="Bart Simpson"

了解和增强您对 YQL 的理解的一种好方法就是使用 YQL 控制台,这是由 Yahoo! 提供的,地址如下: http://developer.yahoo.com/yql/console/。(图 2 展示了屏幕快照。)

请尝试将本文中提供的任何 YQL 语句复制并粘贴到 YQL 控制台中,以查看所得到的 JSONP 响应(务必选中单选按钮,以获得 JSON 输出格式而非 XML)。


图 2. YQL 控制台


使用 jQuery 查询 YQL

典型 YQL GET 请求形式如下:

http://query.yahooapis.com/v1/public?q=[command]&[query parameter]

其中 command 是 YQL 命令,query parameter 表示服务的可选参数。由于目前关注的是 YQL 的 JSONP 支持,因而您的请求必须始终包含两个可选参数,这样才能从 YQL 服务获得 JSONP 响应。您的请求将使用如下格式:

http://query.yahooapis.com/v1/public?q=[command]&format=json&callback=?

其中 format 是定义请求响应格式的请求参数,callback 是 Web 应用程序中回调函数的名称,本例中由 jQuery 提供。请注意,我们使用? 表示回调函数名,而未使用实际函数名,这是为了告诉 jQuery 为我们生成一个函数。

在 jQuery 中,典型的 YQL 服务调用如示例2 所示。


示例2. jQuery 中典型的 YQL 调用

jQuery.getJSON(yqlUrl,function(data) {
// data is the JSON response
// process the response here
}); 

构建 mashup

您已经了解了如何通过 YQL 查询和获得 JSONP 响应,下面就可以开始构建 mashup Web 页面了。我们将开发一个带有三个小部件的 Web 页面,各个小部件分别从 Web 的不同部分获取内容,但使用的是相同的统一服务 —— 即 YQL。

第一个小部件是股票报价小部件,查询并检索 IBM®、Yahoo!、Google 和 Microsoft® 的最新股票报价。此查询的数据源是 Yahoo! Finance CSV 文件。示例 3 显示了第一个小部件的 YQL 代码。


示例 3. 第一个小部件(股票报价)的 YQL 代码
select symbol,price from csv 
  where url='http://download.finance.yahoo.com/d/quotes.csv?
  s=IBM,YHOO,GOOG,MSFT&f=sl1d1t1c1ohgv&e=.csv' and 
  columns='symbol,price,date,time,change,col1,high,low,col2'

第二个小部件显示纽约时报 RSS 提要的标题,通过示例 4 所示的 YQL 代码获取数据。


示例 4. 第二个小部件(RSS 提要)的 YQL 代码
select title,link from rss 
  where url="http://www.nytimes.com/services/xml/rss/nyt/HomePage.xml"

第三个也是最后一个小部件是气象预报小部件,如示例 5 所示,显示邮编 10504 地区的气象预报(纽约 Armonk):


示例 5. 第三个小部件,气象预报
select * from weather.forecast where location=10504

在 Web 页面中,各小部件具有如示例 6 所示的主干代码。


清单 6. 各小部件的主干代码
<div class="widget">
  <div class="widget-head">[WIDGET HEADER]</div>
  <div class="widget-content" id="[CONTENT ID]">[WIDGET CONTENT]</div>
</div>

每个小部件都是类类型为 widget 的一个 div 元素,具有头部(widget-head)和内容区(widget-content)。小部件的内容区由您的 JavaScript 代码填充,拉入 JSONP 数据并将其附加到小部件的内容部分。

构建 mashup Web 页面时,首先要定义三个小部件占位符:一个用于股票报价、一个用于纽约时报新闻、一个用于气象预报。如示例 7 所示。


示例 7. 小部件占位符
<div class="widget">
  <div class="widget-head">Lastest stock quotes</div>
  <div class="widget-content" id="quotes"></div>
</div>   
<div class="widget">
  <div class="widget-head">NYT news headlines</div>
  <div class="widget-content" id="headlines"></div>
</div>   
<div class="widget">
  <div class="widget-head">Weather for Armonk NY</div>
  <div class="widget-content" id="weather"> </div>
</div>   

请注意,内容区保留为空,因为您要使用 JSONP,用动态数据填充内容区。很快您就会看到,jQuery 使得动态生成 HTML 片段变得极为简单。这些区域中的每一个都将由示例 所示的 jQuery 主干代码填充。


示例 8. jQuery 主干代码
$.getJSON(yqlUrl,function(data){
  // loop through the items
  $.each(data.query.results.[ITEM NAME],function(index,item){
    // process each item here
    // generate HTML to append to the widget's content area
  });
});

示例 8 所示的代码向 yqlUrl(您必须提供)发出 GET 请求,并拉取 JSONP 响应。JSONP 响应到达之后(我们称之为data),您就可以遍历结果项,逐个加以处理。[ITEM NAME] 是占位符,代表结果项数组,根据数据源的不同,该数组可能具有不同的名称。使用上文提到的 YQL 控制台查看得到的响应,确定正确的响应结构。


第一个小部件

示例 9 展示了填充股票报价小部件内容的第一个 jQuery 代码段:


示例 9. 第一个小部件的 JavaScript 代码
				
var yqlUrl1= "http://query.yahooapis.com/v1/public/yql?q=
  select%20symbol%2C%20price%20from%20csv%20
  where%20url%3D'http%3A%2F%2Fdownload.finance.yahoo.com%2Fd%2Fquotes.csv%3F
  s%3DIBM%2CYHOO%2CGOOG%2CMSFT%26f%3Dsl1d1t1c1ohgv%26e%3D.csv'%20and%20
  columns%3D'symbol%2Cprice%2Cdate%2Ctime%2Cchange%2Ccol1%2Chigh%2Clow%2Ccol2'
  &format=json&callback=?";
$.getJSON(yqlUrl1,function(data){
  $.each(data.query.results.row,item){
    $('#quotes')
    .append(
      $('<p/>')
        .append($('<span class="left"/>').text(item.symbol))
        .append($('<span class="right"/>').text('$'+item.price))
      );
    });
});

如何为第一个小部件获得经过合理加密的 URL?查看 YQL 控制台时,您会在屏幕右上角看到一个标题为 “The Rest query” 的部分。成功测试 YQL 语句后,应复制此处的查询字符串,并将其作为getJSON() 函数的第一个参数。

股票报价小部件会遍历结果项,将包含两个 span 元素的 p 元素附加到由 id #quotes 标识的div 元素中。最终得到的内容区 HTML 代码如示例 10 所示。


示例10. 第一个小部件的 HTML 代码
				
 <div id="quotes" class="widget-content">
  <p>
    <span class="left">"IBM"</span>
    <span class="right">$91.51</span>
  </p>
  <p>
    <span class="left">"YHOO"</span>
    <span class="right">$12.22</span>
  </p>
  <p>
    <span class="left">"GOOG"</span>
    <span class="right">$353.11</span>
  </p>
  <p>
    <span class="left">"MSFT"</span>
    <span class="right">$18.12</span>
  </p>
</div>

第二个小部件

完成第一个小部件后,继续处理第二个。


示例 11. 第二个小部件的 JavaScript 代码
				
var yqlUrl2= "http://query.yahooapis.com/v1/public/yql?q=
  select%20title%2C%20link%20from%20rss%20
  where%20url%3D%22http%3A%2F%2Fwww.nytimes.com%2Fservices%2Fxml%2Frss%2Fnyt%2F
  HomePage.xml%22&format=json&callback=?";
$.getJSON(yqlUrl2,function(data){
  $.each(data.query.results.item,item){
    $("<a href='" + item.link + "' target="_blank\"/>")
    .html(item.title)
    .appendTo($('#headlines'))
    .wrap('<p/>');
  });
});
			

示例 11 所示代码首先拉取 NYT RSS 提要的 titlelink 元素。随后将包括正文链接的p 元素附加到小部件的内容区。最终得到的内容区 HTML 代码如示例 12 所示。


示例 12. 第二个小部件的 HTML 代码
				
<div id="headlines" class="widget-content">
  <p>
    <a target="_blank" href="http://www.nytimes.com/2009/02/19/business/19housing.html
    ?partner=rss&emc=rss">Obama Unveils $75 Billion Plan to Fight Home Foreclosures</a>
  </p>
  <p>
    <a target="_blank" href="http://www.nytimes.com/2009/02/19/business/economy/19fed.html
    ?partner=rss&emc=rss">Fed Offers Bleak Economic Outlook</a>
  </p>
  ...
</div>
				

第三个小部件

第三个小部件与前两个差别不大。但需要将 item.description 元素直接附加到内容区,因为其中包含的已经是 HTML 格式的数据。


示例13. 第三个小部件的 JavaScript 代码
				
var yqlUrl3= "http://query.yahooapis.com/v1/public/yql?q=
  select%20*%20from%20weather.forecast%20where%20location%3D10504&
  format=json&callback=?";
$.getJSON(yqlUrl3,function(data){
  $.each(data.query.results.channel,item){
    $('#weather')
    .append($('<p/>').html(item.description));
  });	
});
            

考虑到完整性,我们在示例 14 中整合了上述所有内容(除了用于确定小部件样式的 CSS)。


示例 14. 示例 mashup 页面的 HTML 代码
				
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" 
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
  <head>
    <script type="text/javascript" src="jquery-1.3.1.min.js"/>
    <style type="text/css">
    ...
    </style>
    <title>JSONP Mashup</title>
  </head>
  <body>
    <div class="widget">
      <div class="widget-head">Latest stock quotes</div>
      <div class="widget-content" id="quotes"/>
    </div>
    <div class="widget">
      <div class="widget-head">NYT news headlines</div>
      <div class="widget-content" id="headlines"/>
    </div>
    <div class="widget">
      <div class="widget-head">Weather for Armonk,NY</div>
      <div class="widget-content" id="weather"> </div>
    </div>
    <script type="text/javascript">
      var yqlUrl1="http://query.yahooapis.com/v1/public/yql?q=
        select%20symbol%2C%20price%20from%20csv%20
        where%20url%3D'http%3A%2F%2Fdownload.finance.yahoo.com%2Fd%2Fquotes.csv%3F
        s%3DIBM%2CYHOO%2CGOOG%2CMSFT%26f%3Dsl1d1t1c1ohgv%26e%3D.csv'%20and%20
        columns%3D'symbol%2Cprice%2Cdate%2Ctime%2Cchange%2Ccol1%2Chigh%2Clow%2Ccol2'
        &format=json&callback=?";
      $.getJSON(yqlUrl1,function(data){
        $.each(data.query.results.row,item){
          $('#quotes')
          .append(
            $('<p/>')
            .append($('<span class="left"/>').text(item.symbol))
            .append($('<span class="right"/>').text('$'+item.price))
          );
        });
      });

      var yqlUrl2="http://query.yahooapis.com/v1/public/yql?q=
        select%20title%2C%20link%20from%20rss%20
        where%20url%3D%22http%3A%2F%2Fwww.nytimes.com%2Fservices%2Fxml%2Frss%2Fnyt%2F
        HomePage.xml%22&format=json&callback=?";
      $.getJSON(yqlUrl2,function(data){
        $.each(data.query.results.item,item){
          $("<a href='" + item.link + "' target="_blank\"/>")
          .html(item.title)
          .appendTo($('#headlines'))
          .wrap('<p/>');
        });
      });

      var yqlUrl3= "http://query.yahooapis.com/v1/public/yql?q=
        select%20*%20from%20weather.forecast%20where%20location%3D10504&
        format=json&callback=?";
      $.getJSON(yqlUrl3,function(data){
        $.each(data.query.results.channel,item){
          $('#weather')
          .append($('<p/>').html(item.description));
        });	
      });
    </script>
  </body>
</html>
            

图 3 展示了在撰写本文时所得到的 Web 页面屏幕快照。


图 3. 示例 mashup 页面


结束语

YQL 是一种强大的服务,使您可在无需利用服务器端代理的前提下实现客户端 mashup。与其 JSONP 支持和 jQuery 相结合,YQL 允许您通过一个统一的界面访问 Web 上的结构化数据。在这篇文章中,您了解了如何使用 jQuery 和 YQL,通过短短几行代码构建一个 mashup Web 页面。您可在此代码的基础上加以改进完善。下面是一些提示:

  • 在小部件头部加入一个图片链接,单击此链接可刷新内容区。
  • 提供一个输入字段,允许用户输入股票代码,仅获取所输入股票的报价。
  • 不仅显示 RSS 项的标题和链接,还显示简介内容。

HHA!我现在觉得IBM的东西很棒啊!相当值得学习!加油!

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


文章浏览阅读2.4k次。最近要优化cesium里的热力图效果,浏览了网络上的各种方法,发现大多是贴在影像上的。这么做好是好,但是会被自生添加的模型或者其他数据给遮盖。其次是网上的方法大多数是截取成一个矩形。不能自定义的截取自己所需要的。经过尝试,决定修改下cesium heatmap,让他达到我们需要的要求。首先先下载 cesium heatmap包。其中我们可以看到也是通过叠加entity达到添加canvas的方法绘制到地图上。我们先把这一段代码注释} else {} };
文章浏览阅读1.2w次,点赞3次,收藏19次。在 Python中读取 json文件也可以使用 sort ()函数,在这里我介绍一个简单的示例程序: (4)如果我们想将字符串转换为列表形式,只需要添加一个变量来存储需要转换的字符串即可。在上面的代码中,我们创建了一个名为` read`的对象,然后在文件的开头使用`./`关键字来命名该对象,并在文件中定义了一个名为` json`的变量,并在其中定义了一个名为` json`的字段。比如,我们可以使用 read方法读取 json文件中的内容,然后使用 send方法将其发送到 json文件中。_python怎么读取json文件
文章浏览阅读1.4k次。首字母缩略词 API 代表应用程序编程接口,它是一种设备,例如用于使用编程代码发送和检索数据的服务器。最常见的是,该技术用于从源检索数据并将其显示给软件应用程序及其用户。当您访问网页时,API 的工作方式与浏览器相同,信息请求会发送到服务器,如何在 Windows PC 中手动创建系统还原点服务器会做出响应。唯一的区别是服务器响应的数据类型,对于 API,数据是 JSON 类型。JSON 代表 JavaScript Object Notation,它是大多数软件语言中 API 的标准数据表示法。_api是什么 python
文章浏览阅读802次,点赞10次,收藏10次。解决一个JSON反序列化问题-空字符串变为空集合_cannot coerce empty string ("") to element of `java.util.arraylist
文章浏览阅读882次。Unity Json和Xml的序列化和反序列化_unity json反序列化存储换行
文章浏览阅读796次。reader.readAsText(data.file)中data.file的数据格式为。使用FileReader对象读取文件内容,最后将文件内容进行处理使用。_a-upload 同时支持文件和文件夹
文章浏览阅读775次,点赞19次,收藏10次。fastjson是由国内的阿里推出的一种json处理器,由java语言编写,无依赖,不需要引用额外的jar包,能直接运行在jdk环境中,它的解析速度是非常之快的,目前超过了所有json库。提示:以下是引用fastjson的方法,数据未涉及到私密信息。_解析器用fastjson还是jackson
文章浏览阅读940次。【Qt之JSON文件】QJsonDocument、QJsonObject、QJsonArray等类介绍及使用_使用什么方法检查qjsondocument是否为空
文章浏览阅读957次,点赞34次,收藏22次。主要内容原生 ajax重点重点JSON熟悉章节目标掌握原生 ajax掌握jQuery ajax掌握JSON第一节 ajax1. 什么是ajaxAJAX 全称为,表示异步的Java脚本和Xml文件,是一种异步刷新技术。2. 为什么要使用ajaxServlet进行网页的变更往往是通过请求转发或者是重定向来完成,这样的操作更新的是整个网页,如果我们只需要更新网页的局部内容,就需要使用到AJAX来处理了。因为只是更新局部内容,因此,Servlet。
文章浏览阅读1.4k次,点赞45次,收藏13次。主要介绍了JsonFormat与@DateTimeFormat注解实例解析,文中通过示例代码介绍的非常详细,对大家的学习 或者工作具有一定的参考学习价值,需要的朋友可以参考下 这篇文章主要介绍了从数据库获取时间传到前端进行展示的时候,我们有时候可能无法得到一个满意的时间格式的时间日期,在数据库中显 示的是正确的时间格式,获取出来却变成了时间戳,@JsonFormat注解很好的解决了这个问题,我们通过使用 @JsonFormat可以很好的解决:后台到前台时间格式保持一致的问题,
文章浏览阅读1k次。JsonDeserialize:json反序列化注解,作用于setter()方法,将json数据反序列化为java对象。可以理解为用在处理接收的数据上。_jsondeserialize
文章浏览阅读2.7k次。labelme标注的json文件是在数据标注时产生,不能直接应用于模型训练。各大目标检测训练平台或项目框架均有自己的数据格式要求,通常为voc、coco或yolo格式。由于yolov8项目比较火热,故此本博文详细介绍将json格式标注转化为yolo格式的过程及其代码。_labelme json 转 yolo
文章浏览阅读790次,点赞26次,收藏6次。GROUP_CONCAT_UNORDERED(): 与GROUP_CONCAT类似,但不保证结果的顺序。COUNT_DISTINCT_AND_ORDERED(): 计算指定列的不同值的数量,并保持结果的顺序。COUNT_ALL_DISTINCT(): 计算指定列的所有不同值的数量(包括NULL)。AVG_RANGE(): 计算指定列的最大值和最小值之间的差异的平均值。JSON_OBJECT(): 将结果集中的行转换为JSON对象。COUNT_DISTINCT(): 计算指定列的不同值的数量。_mysql json 聚合
文章浏览阅读1.2k次。ajax同步与异步,json-serve的安装与使用,node.js的下载_json-serve 与node版本
文章浏览阅读1.7k次。`.net core`提供了Json处理模块,在命名空间`System.Text.Json`中,下面通过顶级语句,对C#的Json功能进行讲解。_c# json
文章浏览阅读2.8k次。主要介绍了python对于json文件的读写操作内容_python读取json文件
文章浏览阅读770次。然而,有时候在处理包含中文字符的Json数据时会出现乱码的情况。本文将介绍一种解决Json中文乱码问题的常见方法,并提供相应的源代码和描述。而某些情况下,中文字符可能会被错误地编码或解码,导致乱码的出现。通过适当地控制编码和解码过程,我们可以有效地处理包含中文字符的Json数据,避免乱码的发生。通过控制编码和解码过程,我们可以确保Json数据中的中文字符能够正确地传输和解析。为了解决这个问题,我们可以使用C#的System.Text.Encoding类提供的方法进行编码和解码的控制。_c# json 中文编码
文章浏览阅读997次。【代码】【工具】XML和JSON互相转换。_xml 转json
文章浏览阅读1.1k次。json path 提取数据_jsonpath数组取值
文章浏览阅读3w次,点赞35次,收藏36次。本文主要介绍了pandas read_json时ValueError: Expected object or value的解决方案,希望能对学习python的同学们有所帮助。文章目录1. 问题描述2. 解决方案_valueerror: expected object or value