April 13,2006 22:32

JSON

之前第一次看到 JSON 時,我的腦袋就浮現一個 idea - 「這個東西一定很有看頭,跟 Web UI Framework 整合一定是很棒的作法」,不過那個時候我還很忙,工作很忙,回家也有其他事要忙,根本沒時間細想怎麼來實作,只是覺得很棒而已,只在 todo list 中記下「JSON, integrate with UI framework, Cool idea~」,直到最近,稍稍可以喘口氣了,同時又看到另外一篇文章的介紹 - Speeding UP AJAX with JSON,裡頭講了如何用 JSON 來改進 AJAX ap,想法大致都差不多,應該說 JSON 好像也有部分原因是為了 AJAX 而存在,事實上不一定如此,但是 JSON 的出現同時方便了 AJAX 實作。Anyway,我現在也只有一個想法的 picture,還需要經過實作的驗證來證明我這個想法是否實用,不過還是先記一篇 blog 來講一下什麼是 JSON,以及 JSON 與 AJAX,大體而言就是「Speeding UP AJAX with JSON」的中文版再加上我的胡言亂語。

Javascript Object and Array Notation

在介紹 JSON 之前,先來看看 Javascript 是怎麼表示物件跟陣列的。

<<陣列>>

你可以建立一個陣列物件,其中包含該有的元素,如下:
var myArray = new Array ("Hero", "Euro", "MyCat");
此外,你也可以這樣表示一個陣列:
var myArray = ["Hero", "Euro", "MyCat"];
Javascript 的陣列是混和式的陣列,你可以在一個陣列中包含各種型態的物件,字串、數字或者自建物件等,通通都可以。


<<物件>>

你可以以如下程式建立一個新物件:
var myCat = new Object();
myCat.name = "Hero";
myCat.age = 5;
myCat.color = "silver";

此外,你也可以用底下的方式來代表一個新物件:
var myCat = {
	"name": "Hero",
	"age": 5,
	"color": "silver"
};

alert(myCat.name);
alert(myCat.age);
alert(myCat.color);

alert(myCat["name"]);
alert(myCat["age"]);
alert(myCat["color"]);

再來,陣列物件混和使用:
var myCats = [
	{
		"name": "Hero",
		"age": 5,
		"color": "silver"
	},
	{
		"name": "Euro",
		"age": 2,
		"color": ["brown", "white", "black"]
	}
];
alert(myCats[0].name);
alert(myCats[1].age);

什麼是 JSON?


OK,你已經知道 JSON 是什麼了,上面講的 Javascript Object and Array notation 就是 JSON 了,物件陣列的文字表示法就是 JSON 的精神,因此 JSON 全名就是「JavaScript Object Notation」,Nothing more。

一個簡單的 JSON 範例如下:
{
	"myCats": [
		{
			"name": "Hero",
			"age": 5,
			"color": "silver"
		},
		{
			"name": "Euro",
			"age": 2,
			"color": ["brown", "white", "black"]
		}
	]
}

這樣看來,JSON 有什麼用?有什麼鳥不起的?事實上,你可以當它是種資料交換格式,就像 XML 一樣,你可以將這兩種格式視為相同,可以戶轉,但是不是絕對等於,也不能互相取代。

舉例來說,上面的 JSON 我們可以改寫成如下的 XML 文件:

<myCats>
	<cat>
		<name>Hero</name>
		<age>5</age>
		<color>silver</color>
	</cat>
	
	<cat>
		<name>Euro</name>
		<age>2</age>
		<color>brown</color>
		<color>white</color>
		<color>black</color>
	</cat>
</myCats>

XML 是一種很好的表示式,但有時候它就是太囉唆了,JSON 可以簡化這種表示式,用較少的字元達到相同的效果。但是你卻不能將這兩種格式視為相等,有時候是反轉不過來的,例如:

<myCats>
	<cat name="Hero">
		<age>5</age>
		<color>silver</color>
	</cat>
</myCats>

你還是可以轉成同樣的 JSON,但是要從同樣的 JSON 轉回這個 XML 就不是那麼直覺了,它們之間並沒有定義轉換的規則,怎麼轉換單看每個人實作的不同,轉換時容易產生 ambiguous 的情況,甚至遇到 XML namespace 等更複雜的應用時,JSON 就沒輒了。因此 JSON 很適合應用在 lightweight 的網頁應用,為什麼說適合在網頁應用呢?因為 JSON 是以 Javascript 的 ECMA-262 3rd Edition 的標準為基準,根本就是 Javascript 身上的一塊肉,最佳拍檔非 Javascript 莫屬,而 Javascript 又只有 Web 在用,不過,還是要強調一下,只是適合應用在 Web 上而已,但沒有這樣的限制存在,事實上,你想用在哪就用在哪,例如 Action Script 應該也是可以的,它也是符合 ECMA 標準的語言,不過我沒用過 Action Script,不太清楚是否真的適當。此外,JSON 目前也有各種語言的 Binding 了,詳情請看 JSON 官網 - http://www.json.org/

怎麼用?


舉例,如果你有一串 JSON 的字串,如下:

var json = '{"myCats": [ {"name": "Hero", "age": 5, "color": "silver" }, {"name": "Euro", "age": 2, "color": ["brown", "white", "black"] }]}';

怎麼用?就這樣用:

var obj = eval ("(" + json + ")");
alert('I have ' + obj.myCats.length + ' cats.');
alert(obj.myCats[0].name);
alert(obj.myCats[1].name);

利用 eval() 來將 JSON 字串轉成物件,不過字串的前後記得要加上刮號 (),這是用來告知 Javascript Interpreter 這是個物件描述,不是要執行的 statement。

但是呼叫 eval() 是危險的,因為他會執行任何字串中的 Javascript 程式碼,容易有 XSS 攻擊的危險,所以一般都建議引用官網上所提供的 parser - http://www.json.org/json.js 。

var obj = JSON.parse(json);
alert('I have ' + obj.myCats.length + ' cats.');
alert(obj.myCats[0].name);
alert(obj.myCats[1].name);

此外,你也可以把一個物件轉換成 JSON 字串:

<script type="text/javascript" src="http://www.json.org/json.js"></script>
<script type="text/javascript">
var obj = new Object();
obj.myCats = new Array(new Object(), new Object());
obj.myCats[0].name = "Hero";
obj.myCats[0].age = 5;
obj.myCats[0].color = "silver";
obj.myCats[1].name = "Euro";
obj.myCats[1].age = 2;
obj.myCats[1].color = ["black", "white", "brown"];
alert(JSON.stringify (obj));
</script>

真是酷啊~

跟 AJAX 何干?


實作 AJAX 時,我們通常有兩種作法:

1. 伺服器回傳一段 Javascript 由瀏覽器去執行。

2. 伺服器回傳一段 XML 由瀏覽器去讀取詮釋。

一個控制權在伺服器端,一個則是在用戶端,各有好處,用的時機也不太一樣。

但是如果回傳的是一份 XML 文件,我們通常透過 DOM 模型去 parse,如下:

function onRcvData(req) {
	if (req.readyState == 4) {
		if (req.status == 200) {
			cats = req.responseXML.getElementsByTagName('cat');
			for (var i = 0; i < cats.length; i++) {
				var name = cats.getElementsByTagName('name')[0];
				var color = cats.getElementsByTagName('color');
			}
		}
	}
}

看到缺點了吧,就是很麻煩,打那麼多字。不過如果是用 JSON 的話:

function onRcvData(req) {
	if (req.readyState == 4) {
		if (req.status == 200) {
			borg = eval ('(' + req.responseText + ')');
			var name = borg.cat[0].name;
			var color = borg.cat[0].color;
		}
	}
}

簡單明嘹又直覺,這就是運用 JSON 的優點,而且跟 Javascript 搭配起來比 XML 合得多。

其實除了 AJAX 外,一般 Web UI 應用應該也是可以運用 JSON 的,現在一般的 UI 設計都是以伺服器端的 PHP、ASP、CGI 等依據資料來控制網頁的編排,但是有時候為了 DHTML 設計,又非得在用戶端的瀏覽器上利用 Javascript 做變動,同樣的 UI 設計卻需要同時在兩端做考量,網頁設計師與程式設計師的溝通就變的複雜,如何改進?我的想法是,底層 PHP、ASP、CGI 等就一次把前端所需要的資料寫在網頁上,要怎麼安排介面,只需要修改 Javascript 即可,前端程式有了資料後可以自由安排版面配置,後端程式只需要關心如何從資料庫撈資料就好,所以既然如此,最好的資訊呈現方式就非 JSON 莫屬了,Javascript 的一塊肉。資料回存資料庫也類似,JSON 也可以與 PHP 的物件互轉,同樣可以在用戶端將資訊轉成 JSON 格式,到了伺服器端,轉換成物件,一樣可以做資料檢查驗證等,甚至轉換成 SQL,回存資料庫。

不過這只是我一個概念而已,我也不曉得是不是真的好。


  • syshen 發表於樂多回應(17)引用(4)Programming編輯本文
    樂多分類:網路/3C切換閱讀版型 │昨日人次:1 │累計人次:42894
    贊助商廣告
     

    引用URL

    http://cgi.blog.roodo.com/trackback/1410294
    引用列表:
    一種在 JavaScript 直接建立物件的方式,而且還可以利用這種方式在網路上傳遞 JS 的物件資訊,稱為 JSON (JavaScript Object Notation)。
    自製 JavaScript 物件【網站製作學習誌】 at June 6,2006 14:59
    寫 javascript 對一般的網頁程式設計人員來說, 應該是家常便飯, 舉凡一些需要在 client side 完成的事, 大多會利用 javascript 來操作, 例如滑鼠經過換色, 或是檢查 form (表單)在送出前的一些資料正確性檢查(ps. 一定要記得在 server side 也要再次檢查, 以確保資料的正確性)或方便使用者輸入的自動更正等功能. javascript 的功能強大, 又加上高階, 物件化等特性, 使得撰寫 javascript 的程式設計人員十分愛用, 也方便許多在 ..
    有趣的JSON技術【My Program】 at August 21,2006 09:38
    JSON還可以把資料會使用者界面分離. 可以加速CGI的速度. 對embedded system web server很有幫助
    Embedded 系統中的CGI 與 JSON (2)【wls的異想空間】 at June 6,2007 22:06
    以前在看網頁程式設計(PHP, XML)的工具書時,常常會在附錄看到JSON這個名詞,以前一直以為是個很複雜的技術,結果昨天在syshen的blog上看到了一篇JSON的介紹和使用,真是超棒的!我才知道JSON...
    到底什麼是JSON【雜七雜八的kewang部落格 ::PIXNET BLOG::】 at July 21,2007 00:44

    回應文章
    其實這應該也還好, 之前我有稍微看了一下, 其實如果你把XML->Object寫成個固定的function, 意義上也沒多大的不同(差別速度上比較慢而已), 倒是一個需要探討的問題就是, XML到底適不適合在這類的應用上?(AJAX, SOAP.....), 它帶來的Overhead感覺大過於實質上的優點, 唯一最大的優點是, 你可以跟人家講"我用了XML"這樣而已, 嗯, 純粹個人看法, 為了工作, 我還是用了不少XML :P
    | 檢舉 | Posted by Julian Shen at April 14,2006 09:49
    解釋的很好, 也很清楚.. :)
    | 檢舉 | Posted by YuanYuan at June 8,2006 14:45

    你的這篇文章寫得好詳細, 對於初次接觸JSON的我,很有幫助! Thanks!
    | 檢舉 | Posted by alai at November 21,2007 16:41

    hi alai,
    謝謝,這都是一年半前的文章了,還能帶給你幫助讓我感到非常開心
    | 檢舉 | Posted by syshen at November 21,2007 17:26

    讚..
    非常易懂..
    | 檢舉 | Posted by W at May 6,2008 12:29
    講得很清楚,感謝~~ ^^
    | 檢舉 | Posted by Sylvia at March 26,2009 17:30

    非常深入淺出,還連帶讓我瞭解許多相關觀念,真是太讚了!甘溫!
    | 檢舉 | Posted by charleen at October 7,2009 18:19

    我inclue json.js 會發生JSON未被定義的錯誤, 查到一篇文說要用 json2.js, 解決了這個錯誤.
    如下:
    原:

    改:
    供大大參考.
    | 檢舉 | Posted by charleen at October 7,2009 19:19

    我inclue json.js 會發生JSON未被定義的錯誤, 查到一篇文說要用 json2.js, 解決了這個錯誤.
    如下:
    原: <script type="text/javascript" src="http://www.json.org/json.js"></script>

    改: <script type="text/javascript" src="http://www.json.org/json2.js"></script>
    供大大參考.
    | 檢舉 | Posted by charleen at October 7,2009 19:21
    讚!我喜歡!
    | 檢舉 | Posted by slv922 at October 19,2009 12:26

    好文~!對我很有幫助
    | 檢舉 | Posted by Joseph at November 17,2009 10:29

    寫的很好....
    | 檢舉 | Posted by 小米 at July 13,2010 10:01
    私密回應
    Posted at August 27,2010 18:00

    thanks! 寫得太好了!
    | 檢舉 | Posted by kuo at February 23,2011 15:06

    寫的真好!
    | 檢舉 | Posted by JERRY at June 5,2011 21:53

    比起照本宣科的 JSON 介紹網頁,這一篇真是太令人感動了,終於初步瞭解了~
    | 檢舉 | Posted by Shawn at October 1,2012 19:26
    我是網頁初學者..主管丟了一個測試
    懇請大大們賜教!
    內容:給了一個json檔案 (存在 http://localhost/IngridTestSample/JSONTest1.php )

    字串是: [{"name":"John Smith","title":"Manager","boarding_year":"1998","day_of_birth":"1972-01-02"},{"name":"Mary Lee Jones","title":"Assistant Manager","boarding_year":"1999","day_of_birth":"1982-02-08"},{"name":"David Handson","title":"Engineer","boarding_year":"2000","day_of_birth":"1989-03-02"},{"name":"Alexander Dogeman","title":"Engineer","boarding_year":"2001","day_of_birth":"1978-04-01"},{"name":"Black Pete","title":"Assistant","boarding_year":"2002","day_of_birth":"1962-10-02"}]

    需在網頁上設計表格,以上資料會呈現在表格裡
    我什麼都不懂..不知怎麼寫..
    是否可請請您教導? 謝謝您!
    | 檢舉 | Posted by inyu at December 26,2013 11:45