Jquery和Jsonp

随着公开提供的 Web 服务 API 不断增加,现在可以轻松地从不同 Web 源获取资源并构建 mashup —— 只要您能访问正确的 API 和工具。探究如何能够结合高深的跨域调用技术(JSONP)和灵活的 JavaScript 库(jQuery),以快速构建强大的 mashup。

简介

Asynchronous JavaScript and XML (Ajax) 是驱动新一代 Web 站点(流行术语为 Web 2.0 站点)的关键技术。Ajax 允许在不干扰 Web 应用程序的显示和行为的情况下在后台进行数据检索。使用 XMLHttpRequest 函数获取数据,它是一种 API,允许客户端 JavaScript 通过 HTTP 连接到远程服务器。Ajax 也是许多 mashup 的驱动力,它可将来自多个地方的内容集成为单一 Web 应用程序。

不过,由于受到浏览器的限制,该方法不允许跨域通信。如果尝试从不同的域请求数据,会出现安全错误。如果能控制数据驻留的远程服务器并且每个请求都前往同一域,就可以避免这些安全错误。但是,如果仅停留在自己的服务器上,Web 应用程序还有什么用处呢?如果需要从多个第三方服务器收集数据时,又该怎么办?

理解同源策略限制

同源策略阻止从一个域上加载的脚本获取或操作另一个域上的文档属性。也就是说,受到请求的 URL 的域必须与当前 Web 页面的域相同。这意味着浏览器隔离来自不同源的内容,以防止它们之间的操作。这个浏览器策略很旧,从 Netscape Navigator 2.0 版本开始就存在。

克服该限制的一个相对简单的方法是让 Web 页面向它源自的 Web 服务器请求数据,并且让 Web 服务器像代理一样将请求转发给真正的第三方服务器。尽管该技术获得了普遍使用,但它是不可伸缩的。另一种方式是使用框架要素在当前 Web 页面中创建新区域,并且使用 GET 请求获取任何第三方资源。不过,获取资源后,框架中的内容会受到同源策略的限制。

克服该限制更理想方法是在 Web 页面中插入动态脚本元素,该页面源指向其他域中的服务 URL 并且在自身脚本中获取数据。脚本加载时它开始执行。该方法是可行的,因为同源策略不阻止动态脚本插入,并且将脚本看作是从提供 Web 页面的域上加载的。但如果该脚本尝试从另一个域上加载文档,就不会成功。幸运的是,通过添加 JavaScript Object Notation (JSON) 可以改进该技术。

JSON 和 JSONP

JSON 是用于在浏览器和服务器之间交换信息的轻量级数据格式(与 XML 相比)。JOSON 依赖于 JavaScript 开发人员,因为它是 JavaScript 对象的字符串表示。例如,假设有一个含两个属性的 ticker 对象:symbol 和 price。这是在 JavaScript 中定义 ticker 对象的方式:
  1. var ticker = {symbol: 'IBM', price: 91.42};
复制代码
并且这是它的 JSON 表示方式:
  1. {symbol: 'IBM', price: 91.42}
复制代码
从 参考资料 查找更多有关 JSON 和将其作为数据内部交换格式的信息。清单 1 定义了一个 JavaScript 函数,调用该函数时会显示 IBM 的股价。(我们没有详细介绍如何将该函数添加到 Web 页面)。

清单 1. 定义 showPrice 函数
  1. function showPrice(data) {
  2.     alert("Symbol: " + data.symbol + ", Price: " + data.price);
  3. }
复制代码
可以将 JSON 数据作为参数传递,以调用该函数:
  1. showPrice({symbol: 'IBM', price: 91.42}); // alerts: Symbol: IBM, Price: 91.42
复制代码
现在准备将这两个步骤包含到 Web 页面,如清单 2 所示。

清单 2. 在 Web 页面中包含 showPrice 函数和参数
  1. <script type="text/javascript">
  2. function showPrice(data) {
  3.     alert("Symbol: " + data.symbol + ", Price: " + data.price);
  4. }
  5. </script>
  6. <script type="text/javascript">showPrice({symbol: 'IBM', price: 91.42});</script>
复制代码
加载页面后,应该看如图 1 所示的警告。

图 1. IBM ticker


至此,本文已展示了如何将静态 JSON 数据作为参数调用 JavaScript 函数。不过,通过在函数调用中动态包装 JSON 数据可以用动态数据调用函数,这是一种动态 JavaScript 插入的技术。要查看其效果,将下面一行放入名为 ticker.js 的独立 JavaScript 文件中。
  1. showPrice({symbol: 'IBM', price: 91.42});
复制代码
现在改变 Web 页面中的脚本,使其和清单 3 一样。

清单 3. 动态 JavaScript 插入代码
  1. <script type="text/javascript">
  2. // This is our function to be called with JSON data
  3. function showPrice(data) {
  4.     alert("Symbol: " + data.symbol + ", Price: " + data.price);
  5. }
  6. var url = “ticker.js”; // URL of the external script
  7. // this shows dynamic script insertion
  8. var script = document.createElement('script');
  9. script.setAttribute('src', url);

  10. // load the script
  11. document.getElementsByTagName('head')[0].appendChild(script);
  12. </script>
复制代码

在清单 3 所示的例子中,动态插入的 JavaScript 代码位于 ticker.js 文件中,它将真正的 JSON 数据作为参数调用 showPrice()函数。

前面已经提到,同源策略不阻止将动态脚本元素插入文档中。也就是说,可以动态插入来自不同域的 JavaScript,并且这些域都携带 JSON 数据。这其实是真正的 JSONP(JSON with Padding):打包在函数调用中的 JSON 数据。注意,为了完成该操作,Web 页面必须在插入时具有已经定义好的回调函数,也就是我们例子中的 showPrice()。

不过,所谓的 JSONP 服务(或 Remote JSON Service)是一种带有附加功能的 Web 服务,该功能支持在特定于用户的函数调用中打包返回的 JSON 数据。这种方法依赖于接受回调函数名作为请求参数的远程服务。然后该服务生成对该函数的调用,将 JSON 数据作为参数传递,在到达客户端时将其插入 Web 页面并开始执行。

jQuery 的 JSONP 支持

从 1.2 版本开始,jQuery 拥有对 JSONP 回调的本地支持。如果指定了 JSONP 回调,就可以加载位于另一个域的 JSON 数据,回调的语法为:url?callback=?。

jQuery 自动将 ? 替换为要调用的生成函数名。清单 4 显示了该代码。

清单 4. 使用 JSONP 回调

  1. jQuery.getJSON(url+"&callback=?", function(data) {
  2.     alert("Symbol: " + data.symbol + ", Price: " + data.price);
  3. });
复制代码

为此,jQuery 将一个全局函数附加到插入脚本时需要调用的窗口对象。另外,jQuery 也能优化非跨域调用。如果向同一个域发出请求,jQuery 就将其转化为普通 Ajax 请求。

使用 JSONP 支持的示例服务

在上一个例子中,使用了静态文件(ticker.js)将 JavaScript 动态插入到 Web 页面中。尽管返回了 JSONP 回复,但它不允许您在 URL 中定义回调函数名。这不是 JSONP 服务。因此,如何才能将其转换为真正的 JSONP 服务呢?可使用的方法很多。这里我们将分别使用 PHP 和 Java 展示两个示例。

首先,假设您的服务在所请求的 URL 中接受了一个名为 callback 的参数。(参数名不重要,但是客户和服务器必须都同意该名称)。另外假设向服务发送的请求是这样的:

http://www.yourdomain.com/jsonp/ ... ;callback=showPrice


在这种情况下,symbol 是表示请求 ticker symbol 的请求参数,而 callback 是 Web 应用程序的回调函数的名称。使用清单 5 所示的代码可以通过 jQuery 的 JSONP 支持调用该服务。

清单 5. 调用回调服务

  1. jQuery.getJSON("http://www.yourdomain.com/jsonp/ticker?symbol=IBM&callback=?",
  2. function(data) {
  3.     alert("Symbol: " + data.symbol + ", Price: " + data.price);
  4. });
复制代码

注意,我们使用 ? 作为回调函数名,而非真实的函数名。因为 jQuery 会用生成的函数名替换 ?。所以您不用定义类似于 showPrice() 的函数。

清单 6 显示了用 PHP 实现的 JSONP 服务的一段代码。

清单 6. 用 PHP 实现的 JSONP 服务的代码片段

  1. $jsonData = getDataAsJson($_GET['symbol']);
  2. echo $_GET['callback'] . '(' . $jsonData . ');';
  3. // prints: jsonp1232617941775({"symbol" : "IBM", "price" : "91.42"});
复制代码

清单 7 显示了具有同样功能的 Java™ Servlet 方法。

清单 7. 用 Java servlet 实现的 JSONP 服务

  1. @Override
  2. protected void doGet(HttpServletRequest req, HttpServletResponse resp)
  3.   throws ServletException, IOException {
  4.         String jsonData = getDataAsJson(req.getParameter("symbol"));
  5.         String output = req.getParameter("callback") + "(" + jsonData + ");";

  6.         resp.setContentType("text/javascript");
  7.          
  8.         PrintWriter out = resp.getWriter();
  9.         out.println(output);
  10.         // prints: jsonp1232617941775({"symbol" : "IBM", "price" : "91.42"});
  11. }
复制代码

那么,如果要构建 mashup 应该怎么办,是从第三方服务器收集内容,并在单一的 Web 页面中显示它们吗?答案很简单:您必须使用第三方 JSONP 服务。这种服务并不少。

现成的 JSONP 服务

知道如何使用 JSONP 之后,可以开始使用一些现成的 JSONP Web 服务来构建应用程序和 mashup。下面为接下来的开发项目做准备。(提示:您可以复制特定的 URL 并将其粘贴到浏览器的地址栏,以检查生成的 JSONP 响应)。

Digg API:来自 Digg 的头条新闻:

  1. http://services.digg.com/stories/top?appkey=http%3A%2F%2Fmashup.com&type=javascript
  2. &callback=?
复制代码

Geonames API:邮编的位置信息:

  1. http://www.geonames.org/postalCodeLookupJSON?postalcode=10504&country=US&callback=?
复制代码

Flickr API:来自 Flickr 的最新猫图片:

  1. http://api.flickr.com/services/feeds/photos_public.gne?tags=cat&tagmode=any
  2. &format=json&jsoncallback=?
复制代码

Yahoo Local Search API:在邮编为 10504 的地区搜索比萨:

  1. http://local.yahooapis.com/LocalSearchService/V3/localSearch?appid=YahooDemo&query=pizza
  2. &zip=10504&results=2&output=json&callback=?
复制代码

重要提示

JSONP 是构建 mashup 的强大技术,但不幸的是,它并不是所有跨域通信需求的万灵药。它有一些缺陷,在提交开发资源之前必须认真考虑它们。第一,也是最重要的一点,没有关于 JSONP 调用的错误处理。如果动态脚本插入有效,就执行调用;如果无效,就静默失败。失败是没有任何提示的。例如,不能从服务器捕捉到 404 错误,也不能取消或重新开始请求。不过,等待一段时间还没有响应的话,就不用理它了。(未来的 jQuery 版本可能有终止 JSONP 请求的特性)。

JSONP 的另一个主要缺陷是被不信任的服务使用时会很危险。因为 JSONP 服务返回打包在函数调用中的 JSON 响应,而函数调用是由浏览器执行的,这使宿主 Web 应用程序更容易受到各类攻击。如果打算使用 JSONP 服务,了解它能造成的威胁非常重要。

结束语

在该系列的第一篇文章中,我们讲解了如何结合使用 JSONP 和 jQuery 快速构建强大的 mashup。主要主题包括:

    * 浏览器同源策略的限制以及解决办法
    * 作为一种有效的跨域通信技术,JSONP 能够绕过当前浏览器的同源策略限制
    * JSONP 使 Web 应用程序开发人员能够快速构建 mashup
    * 示例 JSONP 服务及其使用:Ticker 服务

本系列的下一篇文章将介绍 Yahoo! 查询语言(YQL),这种单端点 JSONP 服务允许您跨 Web 查询、过滤和合并数据。最后还使用 YQL 和 jQuery 构建 mashup 应用程序。

 

第 2 部分: 使用 JSONP、jQuery 和 Yahoo! 查询语言构建 mashup

在本系列的第 1 部分中,我们介绍了 JSONP(JSON with Padding),将其作为克服浏览器同源策略限制的一种手段,同时整合和显示来自第三方源的数据。本文将延续上一篇文章的讨论,为您展示如何使用来自 Yahoo! 的 JSONP 服务 Yahoo! 查询语言(YQL),使用 JQuery 构建 mashup Web 页面。

简介

在本系列的第 1 部分中,我们介绍了 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 极为相似:

  1. SELECT fields FROM source_table WHERE filter ..
复制代码

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

  1. select title from rss where url="http://www.nytimes.com/services/xml/rss/nyt/HomePage.xml"
复制代码

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

  1. select Title, Address, City, Rating.AverageRating from local.search
  2.   where query="vegetarian" and location="New York, NY" limit 3
复制代码

上面的查询会返回类似于清单 1 的 JSON 响应(忽略所返回的关于查询的元数据)。

清单 1. JSON 查询响应

  1. "results": {
  2.   "Result": [
  3.     {
  4.       "Title": "World of Vegetarian Incorporated",
  5.       "Address": "24 Pell St",
  6.       "City": "New York",
  7.       "Rating": {
  8.         "AverageRating": "5"
  9.       }
  10.     },
  11.     {
  12.       "Title": "Counter",
  13.       "Address": "105 1st Ave",
  14.       "City": "New York",
  15.       "Rating": {
  16.         "AverageRating": "4"
  17.       }
  18.     },
  19.     {
  20.       "Title": "Red Bamboo",
  21.       "Address": "140 W 4th St",
  22.       "City": "New York",
  23.       "Rating": {
  24.         "AverageRating": "4.5"
  25.       }
  26.     }
  27.   ]
  28. }
复制代码

甚至可通过 YQL 查询 Web:

  1. 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 请求形式如下:
  1. http://query.yahooapis.com/v1/public?q=[command]&[query parameter]
复制代码
其中 command 是 YQL 命令,query parameter 表示服务的可选参数。由于目前关注的是 YQL 的 JSONP 支持,因而您的请求必须始终包含两个可选参数,这样才能从 YQL 服务获得 JSONP 响应。您的请求将使用如下格式:
  1. http://query.yahooapis.com/v1/public?q=[command]&format=json&callback=?
复制代码
其中 format 是定义请求响应格式的请求参数,callback 是 Web 应用程序中回调函数的名称,本例中由 jQuery 提供。请注意,我们使用 ? 表示回调函数名,而未使用实际函数名,这是为了告诉 jQuery 为我们生成一个函数。

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

清单 2. jQuery 中典型的 YQL 调用
  1. jQuery.getJSON(yqlUrl, function(data) {
  2. // data is the JSON response
  3. // process the response here
  4. });
复制代码
构建 mashup

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

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

清单 3. 第一个小部件(股票报价)的 YQL 代码
  1. select symbol, price from csv
  2.   where url='http://download.finance.yahoo.com/d/quotes.csv?
  3.   s=IBM,YHOO,GOOG,MSFT&f=sl1d1t1c1ohgv&e=.csv' and
  4.   columns='symbol,price,date,time,change,col1,high,low,col2'
复制代码
第二个小部件显示纽约时报 RSS 提要的标题,通过清单 4 所示的 YQL 代码获取数据。

清单 4. 第二个小部件(RSS 提要)的 YQL 代码
  1. select title, link from rss
  2.   where url="http://www.nytimes.com/services/xml/rss/nyt/HomePage.xml"
复制代码
第三个也是最后一个小部件是气象预报小部件,如清单 5 所示,显示邮编 10504 地区的气象预报(纽约 Armonk):

清单 5. 第三个小部件,气象预报
  1. select * from weather.forecast where location=10504
复制代码
在 Web 页面中,各小部件具有如清单 6 所示的主干代码。

清单 6. 各小部件的主干代码
  1. <div class="widget">
  2.   <div class="widget-head">[WIDGET HEADER]</div>
  3.   <div class="widget-content" id="[CONTENT ID]">[WIDGET CONTENT]</div>
  4. </div>
复制代码
每个小部件都是类类型为 widget 的一个 div 元素,具有头部(widget-head)和内容区(widget-content)。小部件的内容区由您的 JavaScript 代码填充,拉入 JSONP 数据并将其附加到小部件的内容部分。

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

清单 7. 小部件占位符
  1. <div class="widget">
  2.   <div class="widget-head">Lastest stock quotes</div>
  3.   <div class="widget-content" id="quotes"></div>
  4. </div>   
  5. <div class="widget">
  6.   <div class="widget-head">NYT news headlines</div>
  7.   <div class="widget-content" id="headlines"></div>
  8. </div>   
  9. <div class="widget">
  10.   <div class="widget-head">Weather for Armonk NY</div>
  11.   <div class="widget-content" id="weather"> </div>
  12. </div>   
复制代码
请注意,内容区保留为空,因为您要使用 JSONP,用动态数据填充内容区。很快您就会看到,jQuery 使得动态生成 HTML 片段变得极为简单。这些区域中的每一个都将由清单 8 所示的 jQuery 主干代码填充。

清单 8. jQuery 主干代码
  1. $.getJSON(yqlUrl, function(data){
  2.   // loop through the items
  3.   $.each(data.query.results.[ITEM NAME], function(index, item){
  4.     // process each item here
  5.     // generate HTML to append to the widget's content area
  6.   });
  7. });
复制代码
清单 8 所示的代码向 yqlUrl(您必须提供)发出 GET 请求,并拉取 JSONP 响应。JSONP 响应到达之后(我们称之为 data),您就可以遍历结果项,逐个加以处理。[ITEM NAME] 是占位符,代表结果项数组,根据数据源的不同,该数组可能具有不同的名称。使用上文提到的 YQL 控制台查看得到的响应,确定正确的响应结构。

第一个小部件

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

清单 9. 第一个小部件的 JavaScript 代码
  1. var yqlUrl1= "http://query.yahooapis.com/v1/public/yql?q=
  2.   select%20symbol%2C%20price%20from%20csv%20
  3.   where%20url%3D'http%3A%2F%2Fdownload.finance.yahoo.com%2Fd%2Fquotes.csv%3F
  4.   s%3DIBM%2CYHOO%2CGOOG%2CMSFT%26f%3Dsl1d1t1c1ohgv%26e%3D.csv'%20and%20
  5.   columns%3D'symbol%2Cprice%2Cdate%2Ctime%2Cchange%2Ccol1%2Chigh%2Clow%2Ccol2'
  6.   &format=json&callback=?";
  7. $.getJSON(yqlUrl1, function(data){
  8.   $.each(data.query.results.row, function(index, item){
  9.     $('#quotes')
  10.     .append(
  11.       $('<p/>')
  12.         .append($('<span class="left"/>').text(item.symbol))
  13.         .append($('<span class="right"/>').text('如何为第一个小部件获得经过合理加密的 URL?查看 YQL 控制台时,您会在屏幕右上角看到一个标题为 “The Rest query” 的部分。成功测试 YQL 语句后,应复制此处的查询字符串,并将其作为 getJSON() 函数的第一个参数。

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

  15. 清单 10. 第一个小部件的 HTML 代码[code] <div id="quotes" class="widget-content">
  16.   <p>
  17.     <span class="left">"IBM"</span>
  18.     <span class="right">$91.51</span>
  19.   </p>
  20.   <p>
  21.     <span class="left">"YHOO"</span>
  22.     <span class="right">$12.22</span>
  23.   </p>
  24.   <p>
  25.     <span class="left">"GOOG"</span>
  26.     <span class="right">$353.11</span>
  27.   </p>
  28.   <p>
  29.     <span class="left">"MSFT"</span>
  30.     <span class="right">$18.12</span>
  31.   </p>
  32. </div>
复制代码
第二个小部件

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

清单 11. 第二个小部件的 JavaScript 代码
  1. var yqlUrl2= "http://query.yahooapis.com/v1/public/yql?q=
  2.   select%20title%2C%20link%20from%20rss%20
  3.   where%20url%3D%22http%3A%2F%2Fwww.nytimes.com%2Fservices%2Fxml%2Frss%2Fnyt%2F
  4.   HomePage.xml%22&format=json&callback=?";
  5. $.getJSON(yqlUrl2, function(data){
  6.   $.each(data.query.results.item, function(index, item){
  7.     $("<a href='" + item.link + "' target="_blank\"/>")
  8.     .html(item.title)
  9.     .appendTo($('#headlines'))
  10.     .wrap('<p/>');
  11.   });
  12. });
复制代码
清单 11 所示代码首先拉取 NYT RSS 提要的 title 和 link 元素。随后将包括正文链接的 p 元素附加到小部件的内容区。最终得到的内容区 HTML 代码如清单 12 所示。

清单 12. 第二个小部件的 HTML 代码
  1. <div id="headlines" class="widget-content">
  2.   <p>
  3.     <a target="_blank" href="http://www.nytimes.com/2009/02/19/business/19housing.html
  4.     ?partner=rss&emc=rss">Obama Unveils $75 Billion Plan to Fight Home Foreclosures</a>
  5.   </p>
  6.   <p>
  7.     <a target="_blank" href="http://www.nytimes.com/2009/02/19/business/economy/19fed.html
  8.     ?partner=rss&emc=rss">Fed Offers Bleak Economic Outlook</a>
  9.   </p>
  10.   ...
  11. </div>
复制代码
第三个小部件

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

清单 13. 第三个小部件的 JavaScript 代码
  1. var yqlUrl3= "http://query.yahooapis.com/v1/public/yql?q=
  2.   select%20*%20from%20weather.forecast%20where%20location%3D10504&
  3.   format=json&callback=?";
  4. $.getJSON(yqlUrl3, function(data){
  5.   $.each(data.query.results.channel, function(index, item){
  6.     $('#weather')
  7.     .append($('<p/>').html(item.description));
  8.   });       
  9. });
复制代码
考虑到完整性,我们在清单 14 中整合了上述所有内容(除了用于确定小部件样式的 CSS)。

清单 14. 示例 mashup 页面的 HTML 代码
  1. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
  2. "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
  3. <html xmlns="http://www.w3.org/1999/xhtml">
  4.   <head>
  5.     <script type="text/javascript" src="jquery-1.3.1.min.js"/>
  6.     <style type="text/css">
  7.     ...
  8.     </style>
  9.     <title>JSONP Mashup</title>
  10.   </head>
  11.   <body>
  12.     <div class="widget">
  13.       <div class="widget-head">Latest stock quotes</div>
  14.       <div class="widget-content" id="quotes"/>
  15.     </div>
  16.     <div class="widget">
  17.       <div class="widget-head">NYT news headlines</div>
  18.       <div class="widget-content" id="headlines"/>
  19.     </div>
  20.     <div class="widget">
  21.       <div class="widget-head">Weather for Armonk, NY</div>
  22.       <div class="widget-content" id="weather"> </div>
  23.     </div>
  24.     <script type="text/javascript">
  25.       var yqlUrl1="http://query.yahooapis.com/v1/public/yql?q=
  26.         select%20symbol%2C%20price%20from%20csv%20
  27.         where%20url%3D'http%3A%2F%2Fdownload.finance.yahoo.com%2Fd%2Fquotes.csv%3F
  28.         s%3DIBM%2CYHOO%2CGOOG%2CMSFT%26f%3Dsl1d1t1c1ohgv%26e%3D.csv'%20and%20
  29.         columns%3D'symbol%2Cprice%2Cdate%2Ctime%2Cchange%2Ccol1%2Chigh%2Clow%2Ccol2'
  30.         &format=json&callback=?";
  31.       $.getJSON(yqlUrl1, function(data){
  32.         $.each(data.query.results.row, function(index, item){
  33.           $('#quotes')
  34.           .append(
  35.             $('<p/>')
  36.             .append($('<span class="left"/>').text(item.symbol))
  37.             .append($('<span class="right"/>').text('图 3 展示了在撰写本文时所得到的 Web 页面屏幕快照。

  38. 图 3. 示例 mashup 页面
  39. [img]https://i-blog.csdnimg.cn/blog_migrate/2b642a50ef344220bdbfaae922e8d50d.png[/img]

  40. [size=4][b]结束语[/b][/size]

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

  42.     * 在小部件头部加入一个图片链接,单击此链接可刷新内容区。
  43.     * 提供一个输入字段,允许用户输入股票代码,仅获取所输入股票的报价。
  44.     * 不仅显示 RSS 项的标题和链接,还显示简介内容。
  45. +item.price))
  46.       );
  47.     });
  48. });
复制代码
如何为第一个小部件获得经过合理加密的 URL?查看 YQL 控制台时,您会在屏幕右上角看到一个标题为 “The Rest query” 的部分。成功测试 YQL 语句后,应复制此处的查询字符串,并将其作为 getJSON() 函数的第一个参数。

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

清单 10. 第一个小部件的 HTML 代码
  1. @Override
  2. protected void doGet(HttpServletRequest req, HttpServletResponse resp)
  3.   throws ServletException, IOException {
  4.         String jsonData = getDataAsJson(req.getParameter("symbol"));
  5.         String output = req.getParameter("callback") + "(" + jsonData + ");";

  6.         resp.setContentType("text/javascript");
  7.          
  8.         PrintWriter out = resp.getWriter();
  9.         out.println(output);
  10.         // prints: jsonp1232617941775({"symbol" : "IBM", "price" : "91.42"});
  11. }
复制代码
第二个小部件

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

清单 11. 第二个小部件的 JavaScript 代码
  1. http://services.digg.com/stories/top?appkey=http%3A%2F%2Fmashup.com&type=javascript
  2. &callback=?
复制代码
清单 11 所示代码首先拉取 NYT RSS 提要的 title 和 link 元素。随后将包括正文链接的 p 元素附加到小部件的内容区。最终得到的内容区 HTML 代码如清单 12 所示。

清单 12. 第二个小部件的 HTML 代码
  1. http://www.geonames.org/postalCodeLookupJSON?postalcode=10504&country=US&callback=?
复制代码
第三个小部件

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

清单 13. 第三个小部件的 JavaScript 代码
  1. http://api.flickr.com/services/feeds/photos_public.gne?tags=cat&tagmode=any
  2. &format=json&jsoncallback=?
复制代码
考虑到完整性,我们在清单 14 中整合了上述所有内容(除了用于确定小部件样式的 CSS)。

清单 14. 示例 mashup 页面的 HTML 代码
  1. http://local.yahooapis.com/LocalSearchService/V3/localSearch?appid=YahooDemo&query=pizza
  2. &zip=10504&results=2&output=json&callback=?
复制代码
图 3 展示了在撰写本文时所得到的 Web 页面屏幕快照。

图 3. 示例 mashup 页面


结束语

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

    * 在小部件头部加入一个图片链接,单击此链接可刷新内容区。
    * 提供一个输入字段,允许用户输入股票代码,仅获取所输入股票的报价。
    * 不仅显示 RSS 项的标题和链接,还显示简介内容。
+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, function(index, 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, function(index, item){
          $('#weather')
          .append($('<p/>').html(item.description));
        });       
      });
    </script>
  </body>
</html>[/code]图 3 展示了在撰写本文时所得到的 Web 页面屏幕快照。

图 3. 示例 mashup 页面


结束语

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

    * 在小部件头部加入一个图片链接,单击此链接可刷新内容区。
    * 提供一个输入字段,允许用户输入股票代码,仅获取所输入股票的报价。
    * 不仅显示 RSS 项的标题和链接,还显示简介内容。
+item.price))
      );
    });
});[/code]如何为第一个小部件获得经过合理加密的 URL?查看 YQL 控制台时,您会在屏幕右上角看到一个标题为 “The Rest query” 的部分。成功测试 YQL 语句后,应复制此处的查询字符串,并将其作为 getJSON() 函数的第一个参数。

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

清单 10. 第一个小部件的 HTML 代码
  1. @Override
  2. protected void doGet(HttpServletRequest req, HttpServletResponse resp)
  3.   throws ServletException, IOException {
  4.         String jsonData = getDataAsJson(req.getParameter("symbol"));
  5.         String output = req.getParameter("callback") + "(" + jsonData + ");";

  6.         resp.setContentType("text/javascript");
  7.          
  8.         PrintWriter out = resp.getWriter();
  9.         out.println(output);
  10.         // prints: jsonp1232617941775({"symbol" : "IBM", "price" : "91.42"});
  11. }
复制代码
第二个小部件

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

清单 11. 第二个小部件的 JavaScript 代码
  1. http://services.digg.com/stories/top?appkey=http%3A%2F%2Fmashup.com&type=javascript
  2. &callback=?
复制代码
清单 11 所示代码首先拉取 NYT RSS 提要的 title 和 link 元素。随后将包括正文链接的 p 元素附加到小部件的内容区。最终得到的内容区 HTML 代码如清单 12 所示。

清单 12. 第二个小部件的 HTML 代码
  1. http://www.geonames.org/postalCodeLookupJSON?postalcode=10504&country=US&callback=?
复制代码
第三个小部件

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

清单 13. 第三个小部件的 JavaScript 代码
  1. http://api.flickr.com/services/feeds/photos_public.gne?tags=cat&tagmode=any
  2. &format=json&jsoncallback=?
复制代码
考虑到完整性,我们在清单 14 中整合了上述所有内容(除了用于确定小部件样式的 CSS)。

清单 14. 示例 mashup 页面的 HTML 代码
  1. http://local.yahooapis.com/LocalSearchService/V3/localSearch?appid=YahooDemo&query=pizza
  2. &zip=10504&results=2&output=json&callback=?
复制代码
图 3 展示了在撰写本文时所得到的 Web 页面屏幕快照。

图 3. 示例 mashup 页面


结束语

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

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值