讀古今文學網 > 編寫高質量代碼:改善JavaScript程序的188個建議 > 建議144:推薦使用JSON格式進行通信 >

建議144:推薦使用JSON格式進行通信

JSON是一個輕量級並易於解析的數據格式,它按照JavaScript對像和數組字面語法來編寫。下面代碼是用JSON編寫的用戶列表。


[{

\"id\":1,

\"username\":\"alice\",

\"realname\":\"Alice\",

\"email\":\"[email protected]\"

},{

\"id\":2,

\"username\":\"bob\",

\"realname\":\"Bob\",

\"email\":\"[email protected]\"

},{

\"id\":3,

\"username\":\"carol\",

\"realname\":\"Carol\",

\"email\":\"[email protected]\"

},{

\"id\":4,

\"username\":\"dave\",

\"realname\":\"Dave\",

\"email\":\"[email protected]\"

}]


用戶為一個對象,用戶列表為一個數組,與JavaScript中其他數組或對象的寫法相同。這意味著如果對像被包裝在一個回調函數中,JSON數據可以成為能夠運行的JavaScript代碼。在JavaScript中解析JSON可簡單地使用:


function parseJSON(responseText){

return(\'(\'+responseText+\')\');

}


上面的JSON數據也可以提煉成一個更簡單的版本,將名字縮短:


[{

\"i\":1,

\"u\":\"alice\",

\"r\":\"Alice\",

\"e\":\"[email protected]\"

},{

\"i\":2,

\"u\":\"bob\",

\"r\":\"Bob\",

\"e\":\"[email protected]\"

},{

\"i\":3,

\"u\":\"carol\",

\"r\":\"Carol\",

\"e\":\"[email protected]\"

},{

\"i\":4,

\"u\":\"dave\",

\"r\":\"Dave\",

\"e\":\"[email protected]\"

}]


JSON精簡版本將相同的數據以更少的結構和更小的字節尺寸傳送給瀏覽器。也可以完全去掉屬性名,與原格式相比,這種格式可讀性更差,但更利索,文件尺寸非常小:大約只有標準JSON格式的一半。


[

[1,\"alice\",\"Alice\",\"[email protected]\"],

[2,\"bob\",\"Bob\",\"[email protected]\"],

[3,\"carol\",\"Carol\",\"[email protected]\"],

[4,\"dave\",\"Dave\",\"[email protected]\"]

]


解析過程需要保持數據的順序,也就是說,這種精簡格式在進行格式轉換時必須保持和第一個JSON格式一樣的屬性名:


function parseJSON(responseText){

var users=;

var usersArray=(\'(\'+responseText+\')\');

for(var i=0,len=usersArray.length;i<len;i++){

users[i]={

id:usersArray[i][0],

username:usersArray[i][1],

realname:usersArray[i][2],

email:usersArray[i][3]

};

}

return users;

}


在上面代碼中,使用將字符串轉換為一個本地JavaScript數組,然後再將它轉換為一個對像數組,用一個更複雜的解析函數換取了較小的文件尺寸和更快的時間。數組形式的JSON在每一項性能比較中均獲勝,它文件尺寸最小,下載最快,平均解析時間最短。儘管解析函數不得不遍歷列表中所有5000個單元,它的速度還是提高了30%。

當使用XHR時,JSON數據作為一個字符串返回。該字符串通過轉換為一個本地對象。然而,當使用動態腳本標籤插入時,JSON數據被視為另一個JavaScript文件並作為本地碼執行。為做到這一點,數據必須被包裝在回調函數之中,這就是所謂的「JSON填充」或JSONP。下面用JSONP格式編寫用戶列表。


parseJSON([{

\"id\":1,

\"username\":\"alice\",

\"realname\":\"Alice\",

\"email\":\"[email protected]\"

},{

\"id\":2,

\"username\":\"bob\",

\"realname\":\"Bob\",

\"email\":\"[email protected]\"

},{

\"id\":3,

\"username\":\"carol\",

\"realname\":\"Carol\",

\"email\":\"[email protected]\"

},{

\"id\":4,

\"username\":\"dave\",

\"realname\":\"Dave\",

\"email\":\"[email protected]\"

}]);


因為回調包裝的原因,所以JSONP略微增加了文件的尺寸,但與其在解析性能上的改進相比這點增加微不足道。由於數據作為本地JavaScript處理,所以它的解析速度與本地JavaScript一樣快。

JSONP文件大小和下載時間與XHR測試基本相同,而解析時間幾乎快了10倍。標準JSONP的解析時間為0,因為根本用不著解析,它已經是本地格式了。簡化版JSONP和數組JSONP也是如此,只是每種JSONP都需要轉換成標準JSONP直接使用的格式。

最快的JSON格式是使用數組的JSONP格式,雖然這種格式只比使用XHR的JSON略快,但是這種差異隨著列表尺寸的增大而增大。如果所從事的項目需要一個由10 000或100 000個單元構成的列表,那麼使用JSONP比使用JSON好很多。

要避免使用JSONP還有一個與性能無關的原因:JSONP必須是可執行的JavaScript,利用動態腳本標籤注入技術可在任何網站中被任何人調用。從另一個角度來說,JSON在運行之前並不是有效的JavaScript,使用XHR時只是被當做字符串獲取。不要將任何敏感的數據編碼為JSONP,因為無法確定它是否包含私密信息、隨機的URL或cookie。

與XML相比,JSON有許多優點:格式小得多;在總響應報文中,結構佔用的空間更小;數據佔用得更多,特別是在數據包含數組而不是對像時。JSON與大多數服務器端語言的編/解碼庫之間有著很好的互操作性。JSON在客戶端的解析工作微不足道,可以將更多寫代碼的時間放在其他數據處理上。對網頁開發者來說最重要的是,它是表現最好的格式之一,既因為在線傳輸相對較小,也因為解析十分快速。JSON是高性能Ajax的基石,特別是在使用動態腳本標籤插入時。