======================================================
注:本文源代码点此下载
======================================================
简单地说,json 可以将 java script 对象中表示的一组数据转换为字符串,然后就可以在函数之间轻松地传递这个字符串,或者在异步应用程序中将字符串从 web 客户传递给服务器端程序。这个字符串看起来有点儿古怪(稍后会看到几个示例),但是java script 很容易解释它,而且 json 可以表示比名称/值对更复杂的结构。例如,可以表示数组和复杂的对象,而不仅仅是键和值的简单列表。
1.简单 json 示例
按照最简单的形式,可以用下面这样的 json 表示名称/值对:
{ "firstname": "brett" }
这个示例非常基本,而且实际上比等效的纯文本名称/值对占用更多的空间:
firstname=brett
但是,当将多个名称/值对串在一起时,json 就会体现出它的价值了。首先,可以创建包含多个名称/值对的记录,比如:
{ "firstname": "brett", "lastname":"mclaughlin", "email": "brett@newinstance.com" }
从语法方面来看,这与名称/值对相比并没有很大的优势,但是在这种情况下 json 更容易使用,而且可读
性更好。例如,它明确地表示以上三个值都是同一记录的一部分;花括号使这些值有了某种联系。
值的数组
当需要表示一组值时,json 不但能够提高可读性,而且可以减少复杂性。例如,假设您希望表示一个人名
列表。在 xml 中,需要许多开始标记和结束标记;如果使用典型的名称/值对(就像在本系列前面文章中
看到的那种名称/值对),那么必须建立一种专有的数据格式,或者将键名称修改为 person1-firstname 这样
的形式。
如果使用 json,就只需将多个带花括号的记录分组在一起:
{ "people": [
{ "firstname": "brett", "lastname":"mclaughlin", "email": "brett@newinstance.com" },
{ "firstname": "jason", "lastname":"hunter", "email": "jason@servlets.com" },
{ "firstname": "elliotte", "lastname":"harold", "email": "elharo@macfaq.com" }
]}
这不难理解。在这个示例中,只有一个名为 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" }
]
}
这里最值得注意的是,能够表示多个值,每个值进而包含多个值。但是还应该注意,在不同的主条目
(programmers、authors 和 musicians)之间,记录中实际的名称/值对可以不一样。json 是完全动态的,允
许在 json 结构的中间改变表示数据的方式。
在处理 json 格式的数据时,没有需要遵守的预定义的约束。所以,在同样的数据结构中,可以改变表示
数据的方式,甚至可以以不同方式表示同一事物。
在 java script 中使用 json
掌握了 json 格式之后,在 java script 中使用它就很简单了。json 是 java script 原生格式,这意味着在 javascript 中处理 json 数据不需要任何特殊的 api 或工具包。
2.将 json 数据赋值给变量
例如,可以创建一个新的 java script 变量,然后将 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" }
]
}
这非常简单;现在 people 包含前面看到的 json 格式的数据。但是,这还不够,因为访问数据的方式似乎还不明显。
访问数据
尽管看起来不明显,但是上面的长字符串实际上只是一个数组;将这个数组放进 java script 变量之后,就可以很轻松地访问它。实际上,只需用点号表示法来表示数组元素。所以,要想访问 programmers 列表的第一个条目的姓氏,只需在 java script 中使用下面这样的代码:people.programmers[0].lastname;
注意,数组索引是从零开始的。所以,这行代码首先访问 people 变量中的数据;然后移动到称为programmers 的条目,再移动到第一个记录([0]);最后,访问 lastname 键的值。结果是字符串值“mclaughlin”。
下面是使用同一变量的几个示例。
people.authors[1].genre // value is "fantasy"
people.musicians[3].lastname // undefined. this refers to the fourth entry,
and there isn't one
people.programmers.[2].firstname // value is "elliotte"
利用这样的语法,可以处理任何 json 格式的数据,而不需要使用任何额外的 java script 工具包或 api。
3.修改 json 数据
正如可以用点号和括号访问数据,也可以按照同样的方式轻松地修改数据:
people.musicians[1].lastname = "rachmaninov";
在将字符串转换为 java script 对象之后,就可以像这样修改变量中的数据。
转换回字符串
当然,如果不能轻松地将对象转换回本文提到的文本格式,那么所有数据修改都没有太大的价值。在 javascript 中这种转换也很简单:
string newjsontext = people.tojsonstring();
这样就行了!现在就获得了一个可以在任何地方使用的文本字符串,例如,可以将它用作 ajax 应用程序中
的请求字符串。
更重要的是,可以将任何 java script 对象转换为 json 文本。并非只能处理原来用 json 字符串赋值的变量。为了对名为 myobject 的对象进行转换,只需执行相同形式的命令:
string myobjectinjson = myobject.tojsonstring();
4.将 json 发给服务器
将 json 发给服务器并不难,但却至关重要,而且还有一些重要的选择要做。但是,一旦决定使用 json,所要做的这些选择就会十分简单而且数量有限,所以您需要考虑和关注的事情不多。重要的是能够将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" } ] }
如果要以名称/值对将其发送到服务器端,应该如下所示:
var url = "organizepeople.php?people=" + people.tojsonstring();
xmlhttp.open("get", url, true);
xmlhttp.onreadystatechange = updatepage;
xmlhttp.send(null);
这看起来不错,但却存在一个问题:在 json 数据中会有空格和各种字符,web 浏览器往往要尝试对其继续编译。要确保这些字符不会在服务器上(或者在将数据发送给服务器的过程中)引起混乱,需要在 javascript escape() 函数中做如下添加:
var url = "organizepeople.php?people=" + escape(people.tojsonstring());
request.open("get", url, true);
request.onreadystatechange = updatepage;
request.send(null);
该函数可以处理空格、斜线和其他任何可能影响浏览器的内容,并将它们转换成 web 可用字符(比如,空格会被转换成 %20,浏览器并不会将其视为空格处理,而是不做更改,将其直接传递到服务器)。之后,服务器会(通常自动)再把它们转换回它们传输后的本来 “面目”。
这种做法的缺点有两个:
● 在使用 get 请求发送大块数据时,对 url 字符串有长度限制。虽然这个限制很宽泛,但对象的json 字符串表示的长度可能超出您的想象,尤其是在使用极其复杂的对象时更是如此。
● 在跨网络以纯文本发送所有数据的时候,发送数据面临的不安全性超出了您的处理能力。
简言之,以上是 get 请求的两个限制,而不是简单的两个与 json 数据相关的事情。在想要发送用户名和姓之外的更多内容,比如表单中的选择时,二者可能会需要多加注意。若要处理任何机密或极长的内容,可以使用 post 请求。
利用 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 而非 get 打开,而且 content-type 头被设置为让服务器预知它能得到何种数据。在这种情况下,即为 application/x-www-form-urlencoded,它让服务器知道现在发送的是文本,正如它从常规的 html 表单中得到的一样。
另一个简单提示是 url 的末尾追加了时间。这就确保了请求不会在它第一次被发送后即缓存,而是会在此方法每次被调用后重新创建和重发;此 url 会由于时间戳的不同而稍微有些不同。这种技巧常被用于确保到脚本的 post 每次都会实际生成新请求且 web 服务器不会尝试缓存来自服务器的响应。
json 就只是文本
不管使用 get 还是 post,关键之处在于 json 就只是文本。由于不需要特殊编码而且每个服务器端脚本都能处理文本数据,所以可以轻松利用 json 并将其应用到服务器。假如 json 是二进制格式的或是一些怪异的文本编码,情况就不这么简单了;幸好 json 只是常规的文本数据(正如脚本能从表单提交中所接收到的数据,在 post 段和 content-type 头中亦可以看出),所以在将数据发送到服务器时无需太费心。
======================================================
在最后,我邀请大家参加新浪APP,就是新浪免费送大家的一个空间,支持PHP+MySql,免费二级域名,免费域名绑定 这个是我邀请的地址,您通过这个链接注册即为我的好友,并获赠云豆500个,价值5元哦!短网址是http://t.cn/SXOiLh我创建的小站每天访客已经达到2000+了,每天挂广告赚50+元哦,呵呵,饭钱不愁了,\(^o^)/