Ajax和WEB服務(wù)數(shù)據(jù)格式:JSON JSONP
在之前的文章中我們講到了早期的集中數(shù)據(jù)格式,XML,SOAP,HTML。現(xiàn)在,我們來(lái)看看JSON和JSONP。
JSON
JSON(JavaScript Object Notation)是Douglas Crockford提出的。他是一個(gè)輕量級(jí)的數(shù)據(jù)交換格式,基于JavaScript對(duì)象字面量。
我們可以將之前的XML圖書(shū)格式的文件內(nèi)容轉(zhuǎn)換成下面的JSON格式:
- [
- {
- title: "The Principles of Beautiful Web Design, 2nd Edition",
- url: "http://www.sitepoint.com/books/design2/",
- author: "Jason Beaird",
- publisher: "SitePoint",
- price: {
- currency: "USD",
- amount: 39.95
- }
- },
- {
- title: "jQuery: Novice to Ninja",
- url: "http://www.sitepoint.com/books/jquery1/",
- author: "JEarle Castledine & Craig Sharkie",
- publisher: "SitePoint",
- price: {
- currency: "USD",
- amount: 29.95
- }
- },
- {
- title: "Build Your Own Database Driven Website",
- url: "http://www.sitepoint.com/books/phpmysql4/",
- author: "Kevin Yank",
- publisher: "SitePoint",
- price: {
- currency: "USD",
- amount: 39.95
- }
- }
- ]
這是一個(gè)通過(guò)對(duì)象來(lái)表示書(shū)的一種方式,并且有title、url、author、publisher、和price等信息。price是一個(gè)子對(duì)象,并且他包含貨幣類(lèi)型和價(jià)格。
在JavaScript中很容易處理JSON。你可以使用瀏覽器原生的JSON.parse方法或者Douglas Crockford的JSON-js庫(kù)。就算這些都不能用,你也可以使用javaScript的eval方法。不需要再寫(xiě)額外的處理數(shù)據(jù)的方法:
- var json = xhr.responseText;
- var book = JSON.parse(json);
- alert(book[0].title); //first book title
- alert(book[1].url); //second book URL
使用JSON的優(yōu)點(diǎn)在于:
◆ 比XML輕了很多,沒(méi)有那么多冗余的東西
◆ JSON也是具有很好的可讀性的,但是通常返回的都是壓縮過(guò)后的。不像XML這樣的瀏覽器可以直接顯示,瀏覽器對(duì)于JSON的格式化的顯示就需要借助一些插件了
◆ 在JavaScript中處理JSON很簡(jiǎn)單
◆ 其他語(yǔ)言例如PHP對(duì)于JSON的支持也不錯(cuò)
JSON也有一些劣勢(shì):
◆ JSON在服務(wù)端語(yǔ)言的支持不像XML那么廣泛,不過(guò)JSON.org上提供很多語(yǔ)言的庫(kù)
◆ 如果你使用eval()來(lái)解析的話,會(huì)容易出現(xiàn)安全問(wèn)題
盡管如此,JSON的優(yōu)點(diǎn)還是很明顯的。他是Ajax數(shù)據(jù)交互的很理想的數(shù)據(jù)格式。
JSONP (JSON-p)
如果你使用XMLHttpRequest來(lái)調(diào)用JSON的web服務(wù),返回的數(shù)據(jù)可以通過(guò)JSON.parse()或者eval()來(lái)處理。你也可以使用Ajax組件來(lái)做腳本的插入,例如,將遠(yuǎn)程加載的腳本插入在DOM節(jié)點(diǎn)中,通過(guò)script標(biāo)簽調(diào)用:
- var script = document.createElement("script");
- script.src = "http://webservice.com/?a=1&b=2";
- document.getElementsByTagName("head")[0].appendChild(script);
跟XMLHttpRequest不同,插入script標(biāo)簽可以在不同源的情況下獲取其他服務(wù)的數(shù)據(jù)。這對(duì)于流量分析、書(shū)簽工具、小插件、廣告系統(tǒng)來(lái)說(shuō)是很理想的選擇。
不過(guò),返回的JSON數(shù)據(jù)通常都是當(dāng)做本地的代碼立即執(zhí)行。也不會(huì)賦值給變量,所以后面就再訪問(wèn)不到了。不過(guò)這個(gè)問(wèn)題我們可以通過(guò)給網(wǎng)絡(luò)服務(wù)傳遞一個(gè)callback參數(shù)來(lái)進(jìn)行回調(diào):
- var script = document.createElement("script");
- script.src = "http://webservice.com/?a=1&b=2&callback=MyDataHandler";
- document.getElementsByTagName("head")[0].appendChild(script);
這時(shí)候,網(wǎng)絡(luò)服務(wù)通常會(huì)返回一個(gè)包含在一個(gè)回調(diào)函數(shù)中的JSON數(shù)據(jù),這就是JSONP,或者“JSON with padding”,看看代碼:
- MyDataHandler([
- {
- title: "The Principles of Beautiful Web Design, 2nd Edition",
- url: "http://www.sitepoint.com/books/design2/",
- author: "Jason Beaird",
- publisher: "SitePoint",
- price: {
- currency: "USD",
- amount: 39.95
- }
- }
- ...
- ]);
在JSON對(duì)象下載完畢之后,作為參數(shù)傳遞給了MyDataHandler()方法。
JSON和JSONP已經(jīng)是現(xiàn)在最流行的異步交互的數(shù)據(jù)格式了。但是在壓縮傳輸數(shù)據(jù)大小的方面還是可以再研究的。RockUX會(huì)在后面講到關(guān)于自定義數(shù)據(jù)返回。
原文鏈接:http://rockux.com/
看看這一系列其他的文章:
Ajax和WEB服務(wù)數(shù)據(jù)格式:XML SOAP HTML
【編輯推薦】