1. 程式人生 > 其它 >前端開發系列022-基礎篇之JavaScript和JSON(進階)

前端開發系列022-基礎篇之JavaScript和JSON(進階)

title: '前端開發系列022-基礎篇之JavaScript和JSON(進階)'
tags:
  - javaScript系列
categories: []
date: 2017-06-19 08:20:13
在[javaScript和JSON](http://wendingding.com/2018/04/16/javaScript%E7%B3%BB%E5%88%97%20[05]-javaScript%E5%92%8CJSON/)這篇博文中已經對JSON的基礎知識進行了系統的介紹,此文是JSON知識的**進階內容**,本文輸出和JSON有關的以下內容:

❐ JSON核心
❐ JSON的校驗(JSON Schema)

一、JSON核心

JSON是一種資料交換格式,是當前網路通訊中使用的主流資料格式。

JSON本身並不侷限(依賴)於某項特定的技術,非私有且可移植,幾乎所有的現代程式語言(javaScript | java | Ruby | C# | PHP | Object-C等)和平臺都支援對JSON資料的序列化和反序列化處理,JSON主要應用在網路通訊的資料格式Node用來儲存專案元資料Kafka類似的訊息平臺以及MongoDB等NoSQL資料庫中。

JSON流行的主要原因

  • (1) JavaScript語言的復興和崛起
  • (2) JSON自身資料結構的簡潔和緊湊特性
  • (3) 基於JSON的RESTful API呈現大規模增長
  • (4) Ecma國際和IETF相關的標準化工作讓JSON獲得行業認可

JSON的作者Douglas Crockford在創作時借鑑了JavaScript物件字面量的語法,也就是說JSON本身就是JavaScript物件字面量表示法的一個子集和JavaScript開發能夠無縫融合,而JavaScript程式語言的復興和崛起(前端 + Node後端生態)極大的推動了JSON的流行。

JSON的資料表示方式非常簡潔,結構緊湊易於閱讀而且其本身的結構與高階程式語言中的物件|字典|陣列結構天然一致,與XML相比更適合面向物件的設計和開發。此外,JSON格式的文件通常比相同內容的XML文件更小,因此在進行網路傳輸和處理的時候更快、效率更高,JSON本身的這些特性加上相關技術環境的發展讓它逐步替代XML成為網際網路中主要的資料交換格式。

近些年,基於JSON的RESTful API呈現大規模爆炸式增長,包括LinkedIn、Github、Twitter、Facebook、Tumblr和Amazon等公司都提供基於JSON的RESTful API(備註 相關API可以訪問programmableweb查詢)。

JSON的標準化(成為一項技術標準),讓JSON獲得了行業內的認可,下面簡單列出主要的標準化程序。

2001 年 JSON由Douglas Crockford提出。
2006 年 JSON由IETF通過RFC 4627進行首次標準化。
2013 年 Ecma國際通過ECMA 404 將JSON正式標準化。
2014 年 Tim Bray釋出了RFC 7158和RFC 7159作為原始標準的改進版本(主要修正了4627標準中的一些錯誤)。

JSON數值的型別

JSON數值的型別主要指的是在JSON文件中,鍵值對冒號(:)後側值的資料型別,主要包括:

  • null
  • 數值
  • 物件
  • 陣列
  • 字串
  • 布林值

null是JSON中的一個特殊值,用來表示某個key(屬性)沒有值用作佔位符,注意不能由引號括起來。

數值遵循JavaScript雙精度浮點數格式,支援指數形式,但僅支援十進位制數不支援8進位制和16進位制數。

物件由 { 和 } 把鍵值對(key-value)括起來,允許設定為空物件,可以內嵌在其他的物件或者是陣列中。

陣列由 [ 和 ] 把元素括起來,允許設定為空陣列且不限制類型,可以內嵌在其他的物件或者是陣列中。

字串由包含在雙引號間的N(>=0)個Unicode字元組成可包含由轉義字元,但單引號字串是非法的

布林值只存在true和false這兩種值,且不能用引號把它們括起來,需注意JSON中沒有為undefined值。

More ...

版本 ➤JSON的核心標準不會再有新的版本,適用"無版本"理念。

型別 ➤JSON資料在檔案系統中儲存的標準檔案型別為.json,IANA為JSON文件指定的MIME(媒體型別)為application/json

縮排 ➤JSON的編碼規範並不存在與JSON資料縮排相關的話題,主要因為JSON本身是一種序列化格式而非呈現格式,所以縮排對JSON本身而言意義不大,在優化JSON現實的時候,常見的縮排方案是兩格縮排或四格縮排。

工具 ➤

線上生成合法JSON文件的工具(1) JSONmate

線上生成合法JSON文件的工具(2) JSON Editor Online

線上校驗JSON文件是否合法的工具(1) JSON Schema

線上校驗JSON文件是否合法的工具(2) JSON Validate

快速生成大量測試JSON資料的工具推薦 JSON Generator

線上對複雜JSON資料格式化的工具推薦 JSON 線上格式化

建立|編輯JSON檔案的時候,建議使用[JSON Editor Online](https://jsoneditoronline.org)線上工具,上圖是其基本工作介面。

二、JSON Schema

JSON Schema是對JSON文件中的內容、結構和格式進行的宣告,用於校驗JSON文件。區別於普通的JSON校驗工具,JSON Schema能夠對JSON文件執行語法校驗和嚴格的語義校驗JSON Schema這種能夠用於校驗JSON文件內容和語義的工具能夠有效提供服務的安全性,在訊息系統中的應用能夠確保資料格式的正確性,在API設計領域還能夠幫助定義API協議等。

建議

從零開始對JSON文件的內容進行宣告非常麻煩也沒有必要,建議先使用JSONSchema.net網站來根據已有的JSON文件生成對應的Schema文件,然後再根據具體的校驗規則來逐步修繕。

基本示例

這裡先給出一份簡單的JSON文件和對該文件的JSON Schema描述,然後再介紹JSON Schema的核心關鍵詞和具體規則。

# 檔名 demo.json 注意該行不作為json檔案的內容

{
    "name": "wendingding",
    "age": 18,
    "email": "[email protected]",
    "height": 1.73,
    "isGoodMan": true,
    "tags": [
        "javaScript",
        "object-C",
        "C++",
        "swift",
        "php"
    ],
    "car": {
        "type": "A",
        "number": "粵A 66666",
        "price": 21344.88
    }
}

# 檔名 demo-schema.json 注意該行不作為json檔案的內容
{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "type": "object",
  "required": ["name","age","email","height","isGoodMan","tags","car"],
  "properties": {
    "name": {
      "type": "string",
      "examples": [ "wendingding" ],
    },
    "age": {
      "type": "integer",
      "examples": [ 18 ]
    },
    "email": {
      "type": "string",
      "examples": ["[email protected]"],
    },
    "height": {
      "type": "number",
      "examples": [ 1.73 ]
    },
    "isGoodMan": {
      "type": "boolean",
      "examples": [ true]
    },
    "tags": {
      "type": "array",
      "items": {
        "type": "string",
        "examples": ["javaScript", "object-C", "C++","swift","php"]  
      }
    },
    "car": {
      "type": "object",
      "required": ["type","number", "price"],
      "properties": {
        "type": {
          "type": "string",
          "examples": ["A"] 
        },
        "number": {
          "type": "string",
          "examples": ["粵A 66666"]   
        },
        "price": {
          "type": "number",
          "examples": [21344.88 ] 
        }
      }
    }
  }
}

推薦使用命令列工具的validate模組來使用Schema對準備好的JSON文件進行校驗,列出執行細節:

wendingding$ npm install -g ujs-jsonvalidate
/usr/local/bin/validaten -> /usr/local/lib/node_modules/ujs-jsonvalidate/bin/validaten
/usr/local/bin/validate -> /usr/local/lib/node_modules/ujs-jsonvalidate/bin/validate
+ [email protected]
added 4 packages in 7.353s
wendingding$ validate demo.json demo-schema.json 
JSON content in file demo.json is valid

因為在Schema文件中name欄位是必要的,這裡嘗試刪除demo.json文件中的name:"wendingding"部分,然後重新執行校驗會發現提示錯誤資訊。

wendingding$ cat demo.json
{
  "age": 18,
  "email": "[email protected]",
  "height": 1.73,
  "isGoodMan": true,
  "tags": [
    "javaScript",
    "object-C",
    "C++",
    "swift",
    "php"
  ],
  "car": {
    "type": "A",
    "number": "粵A 66666",
    "price": 21344.88
  }
}
wendingding$ validate demo.json demo-schema.json 
Invalid: Missing required property: name
JSON Schema element: /required/0
JSON Content path: 

核心關係詞說明

type 宣告對應欄位的型別。

pattern 使用正則表示式來限定欄位的值。

properties 宣告物件中的欄位,其中包含具體欄位的type值等資訊。

$schema 宣告遵循的JSON Schema標準版本,校驗文件時使用該版本的規則。

items 如果欄位是陣列型別(array),那麼對陣列元素的型別等進行限定。

minimum | maximum 如果是數值型別(number),那麼限定其取值的範圍。

minItems | maxItems 用於校驗陣列成員的數目,設定最小數目和最大數目。

examples 提供該欄位對應值的示例,在建立schema文件的時候通常根據JSON模板檔案的內容生成。

enum 定義固定的列舉值來限制陣列元素的取值,即陣列的元素值只能是enum限定集合中的資料。

additionalProperties 將該欄位設定為false可以禁止JSON文件當前節點中出現額外的欄位。

required 該陣列用於宣告JSON文件中所有的必需欄位,即必需包含這些欄位,否則視為非法文件。

dependencies 設定欄位的依賴關係,即JSON文件中出現了某個欄位的出現必須依賴某個特定欄位。

patternProperties 模式屬性可以基於正則表示式來宣告部分重複的欄位名,如^string[1-3]$

在工作中如果需要對JSON資料進行嚴格的語法和語義校驗,那麼建議先使用典型的JSON文件利用[JSON Schema線上工具](http://json-schema.org)自動生成對應的Schema校驗檔案,然後再對該檔案進行二次編輯,這樣效率會更高一些。

這裡給出JSON Schema線上工具的使用示例。

擴充套件 前文中在對JSON文件和對應Schema進行校驗的時候,在命令列中使用的是validate模組,該模組是JSON Validate網站所對應的npm包,具體使用的是名為ujs-jsonvalidate的處理器。此外,ajv也是Node中優秀的一款JSON校驗類庫,它本身很簡潔且相容性很好,更多資訊可以參考連結地址。