Skip to content

Latest commit

 

History

History
133 lines (109 loc) · 8.08 KB

7.4.3.md

File metadata and controls

133 lines (109 loc) · 8.08 KB

7.4.3 在Ajax应用中操作结构化数据

  目前为止,介绍了服务器响应的数据是纯文本的例子。但是,如果是更加复杂的应用,不仅仅有这样单纯的数据,还有需要处理数组或者对象这样的结构化的数据的情况。这里,我们就来介绍下在Ajax应用中操作这样的结构化的数据的方法。

■Ajax中可以使用的数据形式
  通过Ajax(Asynchronous JavaScript + XML)这个名字,可能会认为「Ajax中处理的数据必须是XML」。但是,在Ajax中XML不是必须的。反而近来Ajax通信中不怎么使用XML了。这是因为有以下理由。

  • 因为有标签,所以数据量更大
  • 容易导致用于操作数据的DOM编程的代码变得冗长

  因此近年来Ajax通信中常用的是称为JSON(JavaScript Object Notation)的形式。例如下面是将书籍信息使用JSON形式来表示的例子。 image image

"Java口袋参考手册"
"技术评论社"

【398页】

  我们可以发现,JSON是基于JavaScript的对象字面量的数据形式。这样有以下优点。

  • 使用JSON.parse方法(3.7.3),就可以直接作为对象读取
  • 和XML相比,数据大小更小

  另外,不仅仅是JavaScript,主要的语言(库)都提供了从对象到JSON形式的转换方法,这已经成为了Ajax技术的一部分了。
  因为只是用作简单的数据交换,所以可以表示的结构是有限制的,但如果只是用于Ajax,基本上没有这样的限制。

■实现「Hatena书签检索功能」
  现在开始我们来看下具体的例子吧。这里介绍的是使用「Hatena书签条目信息获取API」(地址省略……),并在指定的页面中罗列出书签信息的例子。 image

JavaScript完全学习教程
检索
买了一本书
买了一本书
全面介绍

●在指定的页面中罗列对应的书签信息

Note 什么是Web API
  像「Hatena书签条目信息获取API」这样,可以通过网络调用的服务称为Web API。使用Web API,可以将网络上公开的高级功能(或者是数据库)像自己的服务一样使用。例如,「Hatena书签条目信息获取API」,可以对Hatena提供的庞大的书签信息就像是自己的数据库一样进行检索,并且可以自由加工得到的结果并显示。

【399页】

image

客户端
①发送请求
⑤响应最终的结果
自己的应用
应用
④读取Web API的返回值,嵌入到响应中
②通过HTTP调用需要的功能
④使用JSON数据响应处理结果
Web API的提供方(在示例中是「HatenaAPI」)
③根据传递的参数信息,执行检索等需要的处理

●什么是Web API

  那么,我们来看下具体的实现过程吧。

(1)从服务器端访问「Hatena书签条目信息获取API」(下文称为「HatenaAPI」)
  首先,需要在PHP脚本中准备用来访问HatenaAPI的代码。

●清单7-25 bm.php image

// 声明输出字符编码、内部字符编码
// 声明响应的内容类型
// 组合查询HatenaAPI的URL
// 直接输出查询结果

  PHP脚本就不详细介绍了,这里只要理解
创建要查询的URL,并将其结果作为JSON数据输出
这个流程就可以了。

【400页】

  file_get_contents函数以字符串的形式获取访问指定的URL的结果。将bm.php部署到服务器上之后,在浏览器上访问下面这样的URL(URL根据配置的位置而有所不同)。查询信息的「url=」之后设定的是要获取的书签信息的URL。
  下面,是将从浏览器下载下来的内容在不改变其意思的范围内加工为更易读的形式。 image

// 书签个数
// 书签信息
// 书签日期
// 注释
// 用户名
// 标签

  像上面这样,如果可以以JSON的形式获取HatenaAPI的结果就成功了。

(2)创建客户端页面
  确认了服务器端可以正常运行之后,接下来就是在客户端获取服务器端得到的结果并显示在页面上。 image

"检索"
// 点击[检索]按钮时执行的代码

【401页】

image

定义异步通信的处理
// 通信完成时
// 通信成功时
// 从结果访问bookmarks键
// 如果没有书签,显示错误消息
// 如果获取到了书签,列出用户
// 生成<li><a>元素、文本(给<a>元素设定href属性)
// 按照文本 → <a><li><ul>的顺序组合节点
// 将<div id="result">的内容替换为<ul>元素
// 通信失败时
'服务器发生了错误。'
// 通信结束之前
'通信中……'
// 开始和服务器进行异步通信

  可能会觉得这个代码很复杂,但关键点只有粗体字部分。服务器返回的JSON数据可以和清单7-23一样使用responseText属性获取。但是,如果直接这样获取就只是单纯的文本,所以需要使用JSON.parse方法将其转换为JavaScript对象(数组)(①)。

【402页】

  之后,分解转换后的bms对象,组合为<ul><li>列表。因为文档树的组合在6.5节中介绍过了,所以这里的图解就只针对JavaScript对象和文档树的关系进行介绍。请参考清单中的注释来解读。 image

JSON数据
变量data
组合局部的文档树

●读取结果JSON~组合局部文档树的流程

  使用replaceChild方法将生成的<ul><li>列表添加到<div>元素中就完成了。下面是最终生成的<ul>列表的例子。 image image

买了一本书
……中间省略……

【403页】

  理解了上面的内容之后,将bm.html放到和bm.php同一个文件夹中并在浏览器中运行。像P.400的图那样,输入合适的URL,如果可以得到相应的书签列表的话就成功了。

Note 访问外部公开的服务-跨源的限制-
  实际上bm.php的功能只是用来访问HatenaAPI并将其结果直接输出。那么,可能会觉得「直接在bm.html中访问HatenaAPI不就可以了吗?」
  但是,这是不可以的。因为XMLHttpRequest对象由于安全的理由,不允许访问不同的源。就像这个例子,如果要访问外部公开的服务,需要在服务器端准备用于访问服务的应用,然后客户端再访问这个应用。
  像这样,代替客户端来访问外部服务的服务器端代码称为代理。是实现跨域的经典的方法之一。

Note 处理基于XML的Web API
  如果Web API返回XML形式的响应,请使用responseXML属性来代替responseText属性。responseXML属性会将得到的XML文档作为Document对象返回。
  要操作得到的Document对象,可以使用Chapter 6中介绍的DOM。例如下面是从得到的XML文档中获取开头的<title>元素的例子。

●清单 xhr_xml.js image