JavaScript對(duì)象標(biāo)記是基于鍵值對(duì)和有序列表的結(jié)構(gòu)化數(shù)據(jù)基于文本的表示。盡管JSON源自JavaScript,但它在大多數(shù)主要的編程語言中都是通過本地或庫來支持的。JSON通常用于在Web客戶端和Web服務(wù)器之間交換信息。
在過去15年,JSON已經(jīng)在網(wǎng)絡(luò)上普遍存在。今天,它幾乎是所有公開Web服務(wù)的首選格式,同時(shí)也經(jīng)常用于私人網(wǎng)絡(luò)服務(wù)。
JSON的受歡迎程度導(dǎo)致許多數(shù)據(jù)庫的本機(jī)JSON支持。關(guān)系數(shù)據(jù)庫,如PostgreSQL和MySQL,現(xiàn)在支持存儲(chǔ)和查詢JSON數(shù)據(jù)。MongoDB和Neo4j等NoSQL數(shù)據(jù)庫也支持JSON,盡管MongoDB在后臺(tái)使用了稍微修改后的JSON二進(jìn)制版本。
下面我們來看一下JSON,并討論它的來源,它與XML相比的優(yōu)勢和它的缺點(diǎn)等等。首先,我們從一個(gè)例子開始:
上面的結(jié)構(gòu)清楚定義了一個(gè)人的某些屬性。它包括姓氏,已登錄次數(shù),是否為作家,所在公司名稱以及所養(yǎng)寵物名單和類型(在本例中僅一個(gè))。類似于上述的結(jié)構(gòu)可以從服務(wù)器傳遞到web瀏覽器或移動(dòng)應(yīng)用,然后這些應(yīng)用將執(zhí)行諸如顯示數(shù)據(jù)或保存數(shù)據(jù)之類的操作以備日后參考。
JSON是一種通用數(shù)據(jù)格式,其數(shù)值類型最少:字符串,數(shù)字,布爾值,列表,對(duì)象和空值。雖然符號(hào)是JavaScript的一個(gè)子集,但這些類型都以所有常見的編程語言表示,使得JSON成為跨越語言差距傳輸數(shù)據(jù)的良好候選者。
為什么要使用JSON?
要了解JSON的有用性和重要性,我們必須了解一下網(wǎng)絡(luò)互動(dòng)歷史。
在21世紀(jì)初,網(wǎng)絡(luò)上的互動(dòng)開始發(fā)生轉(zhuǎn)變。當(dāng)時(shí),瀏覽器主要作為一個(gè)愚蠢的客戶端顯示信息,服務(wù)器做了所有努力準(zhǔn)備顯示內(nèi)容。當(dāng)用戶點(diǎn)擊瀏覽器中的鏈接或按鈕時(shí),將向服務(wù)器發(fā)送請(qǐng)求,服務(wù)器將所需的信息轉(zhuǎn)換為HTML,瀏覽器會(huì)向用戶呈現(xiàn)一個(gè)HTML頁面。當(dāng)要求瀏覽器重新呈現(xiàn)頁面上的所有內(nèi)容,即使只有一部分頁面已更改,這種模式都是緩慢而低效的。
由于全頁面重新加載成本高昂,因此網(wǎng)頁開發(fā)人員開始尋求更新的技術(shù)來改善用戶體驗(yàn)。同時(shí),在Internet Explorer 5中引入的頁面顯示時(shí),在后臺(tái)進(jìn)行Web請(qǐng)求的能力被證明是加載數(shù)據(jù)以便顯示的可行方法。點(diǎn)擊刷新按鈕不會(huì)重新加載頁面的整個(gè)內(nèi)容,而是觸發(fā)在后臺(tái)加載的Web請(qǐng)求。加載內(nèi)容時(shí),可以使用瀏覽器中的通用編程語言JavaScript(JavaScript)來操縱、保存和顯示數(shù)據(jù)。
最初,數(shù)據(jù)以XML格式傳輸(參見下面的示例),但XML在JavaScript中是冗長和難以管理的。JavaScript已經(jīng)有對(duì)象,這是一種在語言中表達(dá)數(shù)據(jù)的方法,所以Douglas Crockford將該表達(dá)式的一部分作為新的數(shù)據(jù)交換格式規(guī)范,并將其稱為JSON。JSON可以讓人們更容易閱讀,并讓瀏覽器進(jìn)行解析,很快Web開發(fā)人員喜歡JSON就勝過XML了。
到目前為止,JSON是用于在網(wǎng)絡(luò)和移動(dòng)客戶端和后端服務(wù)之間交換數(shù)據(jù)的事實(shí)標(biāo)準(zhǔn)。
JSON與XML
如上所述,JSON替代了XML,XML在新系統(tǒng)中越來越少見,很容易看出為什么。以下是上面那個(gè)示例的XML版本:
除此之外,XML在解析為JavaScript數(shù)據(jù)結(jié)構(gòu)時(shí)也引入了一些歧義。將XML轉(zhuǎn)換為JavaScript對(duì)象可能需要數(shù)十到數(shù)百行代碼,最終需要根據(jù)解析對(duì)象進(jìn)行定制。將JSON轉(zhuǎn)換為JavaScript對(duì)象需要一行代碼,并且不需要有關(guān)解析對(duì)象的任何知識(shí)。
JSON的限制
雖然JSON是一種相對(duì)簡潔,靈活的數(shù)據(jù)格式,易于在許多編程語言中使用,但格式上還是有一些缺點(diǎn)。這里有五個(gè)主要的限制:
1、沒有模式。一方面,這意味著程序員可以完全靈活地以任何方式表示數(shù)據(jù)。另一方面,這意味著可以非常輕松地創(chuàng)建錯(cuò)誤數(shù)據(jù)。
2、僅一個(gè)數(shù)字類型:IEEE-754雙精度浮點(diǎn)格式是很好用的,但它意味著不能利用許多編程語言中可用的多樣和細(xì)微的數(shù)字類型。
3、沒有日期類型。這意味著開發(fā)人員必須使用一些字符串表示日期,這會(huì)導(dǎo)致格式化差異,或者必須以1970年1月1日的形式表示日期。
4、沒有注釋。這使得程序員無法內(nèi)聯(lián)注釋字段,需要添加額外的文檔并會(huì)增加誤解的可能性。
5、雖然JSON不像XML那么冗長,但它也不是最簡潔的數(shù)據(jù)交換格式。對(duì)于大容量或?qū)S梅?wù),需要使用更高效的數(shù)據(jù)格式。
什么時(shí)候應(yīng)該使用JSON?
如果程序員正在編寫與瀏覽器或本地移動(dòng)應(yīng)用程序通信的軟件,則應(yīng)使用JSON作為數(shù)據(jù)格式,使用像XML這樣的格式是一個(gè)過時(shí)的選擇。
在服務(wù)器到服務(wù)器通信的情況下,可能最好使用像Apache Avro或Apache Thrift這樣的序列化框架。JSON不是一個(gè)壞的選擇,仍然可能正是你需要的,但不如上述兩個(gè)效果好。
如果你正在使用NoSQL數(shù)據(jù)庫,在支持JSON作為類型的關(guān)系數(shù)據(jù)庫中,一個(gè)很好的經(jīng)驗(yàn)法則是盡可能少地使用它。針對(duì)符合特定模式的結(jié)構(gòu)化數(shù)據(jù)調(diào)整關(guān)系數(shù)據(jù)庫。雖然大多數(shù)支持JSON形式更靈活的數(shù)據(jù),但在查詢這些JSON對(duì)象屬性時(shí),性能將會(huì)受到影響。
JSON是用于在Web服務(wù)器、瀏覽器和移動(dòng)應(yīng)用程序之間發(fā)送數(shù)據(jù)的格式。其簡單的設(shè)計(jì)和靈活性使其易于閱讀和理解,在大多數(shù)情況下,程序員可以輕松地以所選擇的編程語言進(jìn)行操作。缺乏嚴(yán)格的架構(gòu)可以實(shí)現(xiàn)格式的靈活性,但這種靈活性有時(shí)難以確保正確閱讀和編寫JSON。
程序員可能需要多做一些工作來處理像Scala或Elm這樣的強(qiáng)類型語言中的JSON,但廣泛采用JSON意味著有庫和實(shí)用程序來幫助完成所有最難的部分。 在構(gòu)建新的Web服務(wù)時(shí),選擇JSON可能表示對(duì)相關(guān)領(lǐng)域缺乏了解。