JSON 驗證指的是確認一份文件嚴格符合 ECMA-404 與 RFC 8259 的語法規則,回傳的結果不是綠色的「有效」判定,就是解析失敗所在的確切行號與欄位。要可靠地驗證 JSON,做法是把文件貼進一個和你執行環境使用相同剖析器的工具裡,讀取判定結果,並在上線之前修正任何被回報的位置。這和美化檔案是不同的事:驗證工具不會動你的文字,只回答一個問題——這份 JSON 格式是否正確,如果不正確,究竟是在哪裡出錯?現代瀏覽器內建的原生 JSON.parse 實作,本身就已經符合 RFC 8259,這也是為什麼像JSON Validator這種以瀏覽器為基礎的檢查工具,會和 Node.js、Python 的 json 模組,或正式環境中任何標準函式庫給出一樣的判定結果。這個工具同時還會回報一份結構指紋——最上層型別、最大巢狀深度、鍵總數,以及物件與陣列的數量——讓你在同一個步驟裡,順便檢查 API 回應、設定檔或產生出來的資料負載,形狀是否合理。

how to validate json
如何驗證 json

什麼才算是有效的 JSON

標準 JSON 是由RFC 8259定義的,它規範了每個剖析器都要遵循的詞法與結構規則。一份文件只有在完全遵守這套語法時,才能通過驗證:物件以大括號界定,陣列以中括號界定,每個鍵與每個字串值都必須用雙引號包起來,數字必須寫成固定的詞法形式,而且只允許使用 truefalsenull 這三個字面值。沒有任何空間容許註解,不允許使用單引號,也不會對 NaN 或 Infinity 做任何特殊處理。瀏覽器原生的 JSON.parse 實作的正是這同一套語法,這也是為什麼一個建立在它之上的驗證工具,回傳的判定結果,會和你的 JavaScript 執行環境、Node.js 行程,以及多數 JSON 函式庫在正式環境裡的結果一致——沒有寬鬆猜測、沒有自動修復、也沒有默默容忍。這種嚴格正是它的重點所在:如果你能在本機把它剖析成功,你就知道正式環境裡任何符合規範的消費端,同樣也能剖析成功。

最常見的 JSON 語法錯誤

幾乎每一個「這份 JSON 看起來沒問題」卻失敗的案例,都出自少數幾種語法違規之一。下面列出的錯誤,都是這個驗證工具能精確定位出位置的錯誤,因為它們正好是 RFC 8259 語法會拒絕的內容。舉例來說,一個物件裡同時出現未加引號的鍵、單引號括起來的字串值、陣列最後一個元素後面多出的逗號、JavaScript 風格的單行註解,以及一個超大整數——光是這一小段,就包了剖析器絕不會容忍的五種不同違規,全部都能在同一次驗證裡被抓出來。

錯誤為什麼會失敗快速修法
字串或鍵用單引號括起來RFC 8259 要求每個字串都必須用雙引號改成\"
物件鍵沒有加引號鍵本身也是字串,字串就必須加引號把鍵包在\"…\"
陣列或物件最後一個元素後面多了逗號語法規則在多餘的逗號之前就已經結束刪掉那個逗號
///* */寫註解JSON 沒有註解語法移除註解
NaNInfinity當成數字使用不屬於 JSON 的數字語法改用null或加上引號的字串
括號或大括號沒有配對每一個起始符號都必須有對應的結尾符號數一數符號數量,把它們配對起來

當剖析器遇到上述任何一種情況時,會在出問題的那個字元處停下來,並回報一個位置。不同瀏覽器的錯誤訊息措辭略有不同——Chrome 與 Edge 裡的 V8、Firefox 裡的 SpiderMonkey、Safari 裡的 JavaScriptCore——但不論引擎回報的是哪種格式,JSON Validator 回傳的座標都會被正規化成統一的形式。

一步一步驗證一份 JSON 文件

要驗證 JSON 並根據結果採取行動,最快的方式就是一個緊湊的三步驟循環:貼上、讀判定結果、修正被回報的位置。

  1. 把你的 JSON 貼上或輸入到輸入框裡。
  2. 立即讀取判定結果:一則綠色的「Valid JSON」訊息,或是一個紅色的錯誤區塊,裡面會包含解析失敗所在的確切行號與欄位。
  3. 如果是有效的 JSON,就檢視結構報告——最上層型別、最大深度、鍵總數——藉此檢查你的資料形狀是否合理。

如果判定結果是紅色的,直接跳到編輯器裡對應回報的行號與欄位;剖析器就是在那個確切位置停下來的,訊息裡也會說明它遇到了哪個不該出現的符號。做語法允許範圍內最小幅度的修正,把修正後的文件貼回去,再重新跑一次同樣的檢查。刻意重複這個循環是有道理的:每一次都會把失敗範圍縮小到下一個語法違規,這也是為什麼一個會回報位置的驗證工具,遠比只回傳「語法錯誤」的工具有用得多。

讀懂不同瀏覽器回報的錯誤位置

剖析器自己給出的錯誤訊息,是最可靠的線索,因為它正是由你的應用程式實際會執行的那個引擎所產生的。不過不同引擎的措辭方式各不相同,這也是為什麼一個能把輸出正規化的工具會很有用。Chrome 與 Edge 裡的 V8,通常會回報像「Unexpected token } in JSON at position 42」這樣的訊息,只給出文件中的一個位元組偏移量。Firefox 裡的 SpiderMonkey,回報的訊息比較接近「JSON.parse: expected property name or '}' at line 3 column 7 of the JSON data」,直接給出行號與欄位。Safari 裡的 JavaScriptCore,則採用類似的行號與欄位格式,但用詞略有不同。JSON Validator 會呈現剖析器自身的訊息,只要引擎有提供,也會給出失敗發生的精確行號與欄位——例如「Invalid JSON at line 3, column 7.」。這就把一個模糊的「unexpected token」,變成一個你可以在編輯器裡直接跳過去的具體位置。

結構報告能告訴你什麼

綠色判定結果,只能證明這段文字格式正確,並不能說明它的形狀是否符合你程式碼的預期。結構報告正是為了補上這個缺口,列出這份文件本身的各項事實。

欄位代表的意義
最上層型別objectarraystringnumberbooleannull其中之一
最大深度巢狀結構的最深層級,有助於抓出意外形成遞迴的結構
鍵總數所有層級裡每一個物件鍵的加總
物件數量文件裡出現了多少個{…}區塊
陣列數量文件裡出現了多少個[…]區塊
字元數量貼上的這份文件的長度

這些數字是快速的合理性檢查。一個理應是使用者扁平陣列的回應,卻回報最大深度有九層,就是某處被額外包了一層或被逸出處理過的跡象。一個你原本預期只有少數幾個鍵的設定檔,卻回傳了數千個鍵,就是有重複資料被合併進來的跡象。同一份報告也能幫你在透過緩慢連線傳送資料負載之前,先確認它的大小。

驗證工具 vs. 格式化工具:不同的任務

驗證工具和格式化工具回答的是不同的問題。JSON formatter會美化或壓縮你的文件,方便人閱讀,或方便壓縮資料負載;許多格式化工具也會順帶做有效性檢查。驗證工具則刻意完全不改動文字,只回報正確性、錯誤位置與結構統計數字。當檔案來自你不信任的來源——上游 API、匯出工具、從文件複製貼上的內容——而你需要在程式碼碰它之前先確認它能被解析成功時,就用驗證工具。當檔案已知是有效的,而你需要閱讀它、做差異比對,或把它壓縮變小時,就用格式化工具。同一份文件可以先後跑過這兩種工具,順序不拘。

一個提醒:驗證抓不到什麼

綠色的判定結果只能確認語法正確,不能確認語意正確。有兩個實務上的限制值得知道。第一,JSON 的數字是以 IEEE-754 雙精度浮點數解析的,所以超過 2^53 的整數值會失去精確度——一個透過 JSON.parse 傳遞的 64 位元識別碼,最後可能會變成另一個數字。第二,JSON 驗證並不會強制執行 schema:一份文件可以完全格式正確,卻仍然不符合你要填入的欄位所需要的形狀。若需要 schema 層級的檢查,請把語法驗證,搭配一個了解你的資料應該符合什麼契約的 JSON Schema 驗證工具一起使用。驗證完全在你的瀏覽器裡、用引擎原生的剖析器執行,所以即使是很大或巢狀很深的輸入,也能安全地被處理,不會有任何內容被上傳到伺服器。

如果你還在猶豫該怎麼選,Cron Parser Bulk:驗證每一條五欄位運算式一文有更詳細的說明。

如果你還在猶豫該怎麼選,如何把 URL 查詢字串解析成 JSON一文有更詳細的說明。