220 likes | 423 Views
Ajax 编程技术 第十一章 JSON. 11.1 概述. 向服务器发出 Ajax 请求时,可以以两种不同的方式从服务器响应中检索数据,一种是 responseXML ,一种是 responseText 。前者以 XML 格式检索数据,解析数据比较困难,后者以纯文本格式解析数据。 Douglas Crockford 创建了另一种数据传输格式,我们称之为 JavaScript 对象表示法 (JavaScript Object Notation ) 。它是一种轻量级的数据交换格式。易于人阅读和编写。同时也易于机器解析和生成。它基于 JavaScript 的一个子集。
E N D
11.1 概述 向服务器发出Ajax请求时,可以以两种不同的方式从服务器响应中检索数据,一种是responseXML,一种是responseText。前者以XML格式检索数据,解析数据比较困难,后者以纯文本格式解析数据。 Douglas Crockford创建了另一种数据传输格式,我们称之为JavaScript对象表示法(JavaScript Object Notation )。它是一种轻量级的数据交换格式。易于人阅读和编写。同时也易于机器解析和生成。它基于JavaScript的一个子集。 JSON采用完全独立于语言的文本格式,但是也使用了类似于C语言家族的习惯。这些特性使JSON成为理想的数据交换语言。 11-2
11.2 JSON语法 • JSON构建的结构 • “名称/值”对的集合:A collection of name/value pairs,不同的语言中,它被理解为对象(object),纪录(record),结构(struct),字典(dictionary),哈希表(hash table),有键列表(keyed list),或者关联数组 (associative array)。 • 值的有序列表:An ordered list of values,在大部分语言中,它被理解为数组(array)。 这些都是常见的数据结构。事实上大部分现代计算机语言都以某种形式支持它们。这使得一种数据格式在同样基于这些结构的编程语言之间交换成为可能。 11-3
11.2 JSON语法 • JSON的具体形式 • 对象:一个无序的“‘名称/值’对”集合。对象以“{”开始,以“}”结束。每个“名称”后跟一个“:”,“‘名称/值’对”之间使用“,”分隔。 • 数组:是值(value)的有序集合。数组以“[”开始,“]”结束。值之间使用“,”分隔。 • 值:value,可以是双引号括起来的字符串(String)、数值(number)、true、false、null、对象(object)或者数组(array)。这些结构可以嵌套。 • 字符串:string,由双引号包围的任意数量Unicode字符的集合,使用反斜体转义。一个字符(character)即一个单独的字符串(characeter string)。 11-4
11.2 JSON语法 • 实例比较 XML和JSON都使用结构化方法来标记数据,下面来做一个简单的比较。现假设有一个用户数据包括:用户名、密码、所在部门、性别、年龄。 • 用XML表示如下: • <?xml version="1.0" encoding="utf-8"?> • <user> • <name>张三 </name> • <password>123456</password> • <department>技术部</department> • <sex>男</sex> • <age>30</old> • </user> • 用JSON表示如下: • { "name":"张三", • "password":"123456", • "department":"技术部", • "sex":"男", • " age":30 • } 11-5
11.2 JSON语法 • JSON 数据格式解析 和 XML 一样,JSON 也是基于纯文本的数据格式。并且它们都使用Unicode编码,同样具有可读性。 XML比较适合于标记文档,而JSON却更适合于时行数据交换处理。可以用 JSON 传输一个简单的 String,Number,Boolean,也可以传输一个数组,或者一个复杂的 Object 对象。 String,Number 和 Boolean 用 JSON 表示非常简单。例如,用 JSON 表示一个简单的 String “ abc ”,其格式为:"abc" 11-6
11.2 JSON语法 除了字符 “、\、/ 和一些控制符(\b、\f、\n、\r、\t)需要编码外,其他 Unicode 字符可以直接输出。 • String 的完整表示结构: 11-7
11.2 JSON语法 • Number 可以根据整型或浮点数表示如下。这与绝大多数编程语言的表示方法一致,例如: • 12345(整数) • -3.9e10(浮点数) 11-8
11.2 JSON语法 • Object 对象在 JSON 中是用 {} 包含一系列无序的 Key-Value 键值对表示的,实际上此处的 Object 相当于 Java 中的 Map<String, Object>,而不是 Java 的 Class 。注意 Key 只能用 String 表示。 例如,一个 Address 对象包含如下 Key-Value: city:Beijing street:Chaoyang Roadpostcode:100025 用 JSON 表示如下: {"city":"Beijing","street":" ChaoyangRoad","postcode":100025} 11-9
11.3 JavaScript 处理 JSON 数据 上面介绍了如何用 JSON 表示数据,接下来,我们还要解决如何在服务器端生成 JSON 格式的数据以便发送到客户端,以及客户端如何使用 JavaScript 处理 JSON 格式的数据。 我们先讨论如何在 Web 页面中用 JavaScript 处理 JSON 数据。我们通过一个简单的 JavaScript 方法就能看到客户端如何将 JSON 数据表示给用户: function handleJson() { var j={"name":"Michael", "address": { "city":"Beijing", "street":" Chaoyang Road ", "postcode":100025 } }; document.write(j.name); document.write(j.address.city); } 11-10
11.3 JavaScript 处理 JSON 数据 假定服务器返回的 JSON 数据是上文的: 只需将其赋值给一个 JavaScript 变量,就可以立刻使用该变量并更新页面中的信息了。相比 XML 需要从 DOM 中读取各种节点而言,JSON 的使用非常容易。我们需要做的仅仅是发送一个 Ajax 请求,然后将服务器返回的 JSON 数据赋值给一个变量即可。 {"name":"Michael", "address": { "city":"Beijing", "street":" Chaoyang Road ", "postcode":100025 } }; 11-11
11.3 JavaScript 处理 JSON 数据 有许多 Ajax 框架早已包含了处理 JSON 数据的能力,例如 Prototype(一个流行的 JavaScript 库:http://prototypejs.org)提供了 evalJSON() 方法,能直接将服务器返回的 JSON 文本变成一个 JavaScript 变量: new Ajax.Request ("http://url", { method: "get", onSuccess: function(transport) { var json = transport.responseText.evalJSON(); // TODO: document.write(json.xxx); } } ); 11-12
11.3 JavaScript 处理 JSON 数据 • 通过 GET 以名称/值对发送 JSON 将 JSON 数据发给服务器的最简单方法是将其转换成文本,然后以名称/值对的值的方式进行发送。请务必注意,JSON 格式的数据是相当长的一个对象,如下所示: var people = { "programmers": [ { "firstName": "Brett", "lastName":"McLaughlin", "email": "brett@newInstance.com" }, { "firstName": "Jason", "lastName":"Hunter", "email": jason@servlets.com }, { "firstName": "Elliotte", "lastName":"Harold", "email": elharo@macfaq.com } ], "authors": [ { "firstName": "Isaac", "lastName": "Asimov", "genre": "science fiction" }, { "firstName": "Tad", "lastName": "Williams", "genre": "fantasy" }, { "firstName": "Frank", "lastName": "Peretti", "genre": "christian fiction" } ], "musicians": [ { "firstName": "Eric", "lastName": "Clapton", "instrument": "guitar" }, { "firstName": "Sergei", "lastName": "Rachmaninoff", "instrument": "piano" } ] } 11-13
11.3 JavaScript 处理 JSON 数据 如果要以名称/值对将其发送到服务器端,应该如下所示: 这看起来不错,但却存在一个问题:在 JSON 数据中会有空格和各种字符,Web 浏览器往往要尝试对其继续编译。要确保这些字符不会在服务器上(或者在将数据发送给服务器的过程中)引起混乱,需要在 JavaScript escape() 函数中做如下添加: var url = "organizePeople.php?people=" + people.toJSONString(); xmlHttp.open("GET", url, true); xmlHttp.onreadystatechange = updatePage; xmlHttp.send(null); var url = "organizePeople.php?people=" + escape(people.toJSONString()); xmlHttp.open("GET", url, true); xmlHttp.onreadystatechange = updatePage; xmlHttp.send(null); 11-14
11.3 JavaScript 处理 JSON 数据 escape函数可以处理空格、斜线和其他任何可能影响浏览器的内容,并将它们转换成 Web 可用字符(比如,空格会被转换成 %20,浏览器并不会将其视为空格处理,而是不做更改,将其直接传递到服务器)。之后,服务器会(通常自动)再把它们转换回它们传输后的本来 “面目”。这种做法的缺点有两个: • 在使用 GET 请求发送大块数据时,对 URL 字符串有长度限制。虽然这个限制很宽泛,但对象的 JSON 字符串表示的长度常常超出。 • 在跨网络以纯文本发送所有数据的时候,发送数据面临的不安全性超出了您的处理能力。 简言之,以上是 GET 请求的两个限制,而不是简单的两个与 JSON 数据相关的事情。在想要发送用户名和姓之外的更多内容,比如表单中的选择时,二者可能会需要多加注意。若要处理任何机密或极长的内容,可以使用 POST 请求。 11-15
11.3 JavaScript 处理 JSON 数据 • 利用 POST 请求发送 JSON 数据 当决定使用 POST 请求将 JSON 数据发送给服务器时,并不需要对代码进行大量更改,如下所示: var url = "organizePeople.php?timeStamp=" + new Date().getTime(); request.open("POST", url, true); request.onreadystatechange = updatePage; request.setRequestHeader("Content-Type", "application/x-www-form-urlencoded"); request.send(people.toJSONString()); 请求使用 POST ,而且 Content-Type 设置为让服务器预知得到 何种数据。即为application/x-www-form-urlencoded,它让服务器 知道发送的是文本,正如它从常规的 HTML 表单中得到的一样。 另一个提示是 URL 的末尾追加了时间,以确保请求不会在它被 发送后即缓存,而会在每次被调用后重新创建和重发; 11-16
11.4 PHP的JSON函数 • PHP的JSON函数 PHP5.20以上版本发布了处理JSON数据格式的两个函数: • json_encode ; • json_decode 。 11-17
11.4 PHP的JSON函数 • json_encode • 函数功能:对变量进行 JSON 编码 • 函数格式:string json_encode ( mixed $value ) • 函数返回:value值的 JSON 形式 • 函数参数:value • 待编码的 value,除了resource 类型之外,可以为任何数据类型 • 该函数只能接受 UTF-8 编码的数据(指字符/字符串类型的数据) 11-18
11.4 PHP的JSON函数 • 范例:一个 json_encode() 的例子 <?php $arr = array ('a'=>1,'b'=>2,'c'=>3,'d'=>4,'e'=>5); echo json_encode($arr); ?> 上例将输出: {"a":1,"b":2,"c":3,"d":4,"e":5} 11-19
11.4 PHP的JSON函数 // 一个转换PHP变量成JSON格式的函数function json_format($json){ $tab = " "; $new_json = ""; $indent_level = 0; $in_string = false; $json_obj = json_decode($json); if($json_obj === false) return false; $json = json_encode($json_obj); $len = strlen($json); for($c = 0; $c < $len; $c++) { $char = $json[$c]; switch($char) { case '{': case '[': if(!$in_string) { $new_json .= $char . "\n" . str_repeat($tab, $indent_level+1); $indent_level++; } else { $new_json .= $char; } break; case '}': case ']': if(!$in_string) { $indent_level--; $new_json .= "\n" . str_repeat($tab, $indent_level) . $char; } else { $new_json .= $char; } break; case ':': if(!$in_string) { $new_json .= ": "; } else { $new_json .= $char; } break; case '"': if($c > 0 && $json[$c-1] != '\\') { $in_string = !$in_string; } default: $new_json .= $char; break; } } return $new_json;} 11-20
11.4 PHP的JSON函数 • json_decode • 函数功能:接受一个 JSON 格式的字符串并且把它转换为 PHP 变量 • 函数格式:mixed json_decode ( string $json [, bool $assoc ] ) • 函数返回:返回一个对象,或者当$assoc参数为TRUE时,返回一个数组 • 函数参数: • Value:待解码的 json string 格式的字符串 • $assoc:值为 TRUE 时,将返回 array 而非 object 11-21
11.4 PHP的JSON函数 • 范例:以下是一个通用的函数,它将JSON格式数据转换成数组: <?php function json_code ($json) { //remove curly brackets to beware from regex errors $json = substr($json, strpos($json,'{')+1, strlen($json)); $json = substr($json, 0, strrpos($json,'}')); $json = preg_replace('/(^|,)([\\s\\t]*)([^:]*) (([\\s\\t]*)):(([\\s\\t]*))/s', '$1"$3"$4:', trim($json)); return json_decode('{'.$json.'}', true); } $json_data = '{ a: 1, b: 245, c : "test me", d: "function () { echo \"test\" }", e: 5.66 }';$jarr = json_code($json_data); echo $jarr["a"]."<BR>"; echo $jarr["b"]."<BR>"; echo $jarr["c"]."<BR>"; echo $jarr["d"]."<BR>"; echo $jarr["e"]."<BR>"; ?> 11-22