繁體中文

開發者工具 · JSON 格式化程式和驗證程序

JavaScript 物件文字與 JSON:為什麼單引號驗證失敗

· 工作原理

json 開發人員工作流程 驗證

JavaScript 物件文字與 JSON:為什麼單引號無法透過 JSON 標記和精確驗證邊界進行驗證
原始 ToolAcre 向量圖

JavaScript 控制台列印的物件看起來像 JSON 但通常不是。這篇文章列出了確切的差異(引號、未加引號的鍵、未定義、函數),並顯示了每個差異觸發驗證器的位置。

從控制台出來了,為什麼無效呢?

從控制台出來了,為什麼無效呢? — 開發者控制台將 JavaScript 值顯示為 JavaScript 原始碼文字,而不是有保證的 JSON 序列化。複製的物件可能包含裸屬性名稱、單引號字串、`undefined` 或特定瀏覽器的註解。所有這些對於 JavaScript 引擎或人類讀者來說都是可以理解的,但在 `.json` 檔案中立即失敗,該檔案的語法故意更小並獨立於可執行程式碼。

考慮 `{name: "Ada", active: true, missing: undefined}`。大括號、冒號和布林值類似於 JSON,但第一個裸鍵已經違反了物件成員規則,並 `undefined` 稍後會失敗。 ToolAcre 使用行和列報告第一個不支援的字元或值,因此最好按順序進行轉換。

字串必須使用雙引號

字串必須使用雙引號 — JSON 將字串定義為 `"` 括起來的字符,並在需要時使用反斜杠轉義。單引號沒有字串分隔符號的作用。當驗證器滿足 `'Ada'` 時,它不會以字串開頭然後反對其內容;它拒絕開頭的撇號本身。這同樣適用於屬性名稱和字串值,即使 JavaScript 允許其自己的文字使用任一引號樣式。

轉換引號比全域取代每個撇號更需要小心。一旦數值被雙引號括起來,文字中的撇號(例如 `Ada's profile`)就是普通內容,而該內容中現有的雙引號必須被轉義。有效的 JSON 形式是 `"Ada's "profile""`。

鍵必須是帶引號的字串

鍵必須是帶引號的字串 - JavaScript 物件文字允許識別碼樣式名稱(例如 `{name: 1}`)和計算名稱(例如 `{[expression]: 1}`)。 JSON 不允許這兩種簡寫形式。在左大括號或逗號之後,下一個成員必須以雙引號字串開頭,後面跟著冒號。有效的表示是 `{"name": 1}`。指向 `n` 的驗證器正在識別需要報價的確切位置。

引用每個鍵還可以消除空格、連字符和保留字的歧義。對於這些情況,JavaScript 可能需要不同的來源語法,但 JSON 使用一個一致的規則:`"display-name"`、`"first name"` 和 `"default"` 都是普通成員名稱。看起來數字的鍵也是字串。

值 JSON 根本沒有

值 JSON 完全不存在 — 其值詞彙是物件、陣列、字串、數字、`true`、`false` 和 `null`。沒有 `undefined`、`NaN`、`Infinity`、函數、正規表示式、BigInt 或 Date 文字。語法中沒有註釋,數字不能使用十六進位、二進位、前導加號或 JavaScript 數字分隔符號。每個借用的構造最終都會到達一個無法開始或繼續有效 JSON 值的字元。

轉換需要資料決策而不是拼字技巧。只有當明確空值與應用程式約定相符時,才將 `undefined` 替換為 `null` ;否則刪除成員或提供實際值。將日期編碼為商定的字串,通常為 ISO 8601。根據接收 API 表示非有限數字,而不是發明 JSON 令牌。

工作範例:將控制台轉儲轉換為有效的 JSON

工作範例:將控制台轉儲轉換為有效的 JSON — 以 `{name: 'Ada', active: true, score: NaN, updated: new Date()}` 開頭。以雙引號引用 `name`、`active`、`score` 和 `updated`。將名稱值變更為雙引號字串。確定不可用分數應為 `null`,並將建構函數表達式替換為它要產生的實際時間戳字串。該檔案現在僅包含 JSON 成員和值。

最終形狀可能是 `{"name":"Ada","active":true,"score":null,"updated":"2026-03-21T10:00:00Z"}`。在每個修復類別之後進行驗證,因為第一個錯誤可能會隱藏後面的純 JavaScript 語法。格式化接受的結果然後公開其結構,而不執行任何進一步的轉換。

反向陷阱 — 有效的 JSON JavaScript 會以不同的方式讀取,例如非常大的整數和 __proto__ 鍵

反向陷阱 — 有效的 JSON 在解析後仍然可以獲得 JavaScript 特定的行為或限制。 JSON 數字在語法中沒有內建精度限制,但 JSON.parse 會產生 JavaScript 數字值。因此,超出安全範圍的整數可以靜默舍入。如果每個數字都很重要,請將識別碼編碼為字串,或使用旨在保留任意精確度數字的解析器和資料類型,而不是信任成功的語法檢查。

成員名稱 `"__proto__"` 也是有效的 JSON 並 JSON.parse 將其建立為自己的資料屬性。如果應用程式程式碼將已解析的屬性複製到具有不安全分配或合併行為的另一個物件中,則稍後可能會出現問題。驗證證明文字遵循 JSON 語法;它並不能證明每把鑰匙對每個消費者來說都是安全的。

這不包括什麼

這不包括什麼 - JSON5、JSONC 和故意接受註釋、尾隨逗號、不帶引號的名稱或單引號字串的配置語言。這些格式解決了不同的創作問題,並需要實作自己的語法的解析器。嚴格的 JSON 驗證器不應默默地重新解釋它們,因為接受額外的語法會使其結果誤導真正需要標準 JSON 的 API、包元資料和其他目標。

這個差異也排除任意 JavaScript 評估。透過 `eval` 或 Function 建構子執行貼上的文字只是為了將物件文字轉換為資料,可以執行 getter、呼叫或其他惡意表達式。如果來源是您控制下的受信任 JavaScript,請使用 JSON.stringify 序列化實際值。如果來源是不受信任的文字,則不要執行它。

重點:文字是程式碼,JSON 是資料

重點:文字是程式碼,JSON 是資料-視覺相似性並不意味著它們的語法可以互換。 JSON 需要雙引號字串和成員名稱,僅允許一小部分固定值類型,且不包含註解或可執行表達式。行列診斷標記複製來源離開該語法的第一個位置。修復該點並再次驗證比對控制台轉儲應用廣泛的搜尋和替換更可靠。

當您控制 JavaScript 值時,使用 JSON.stringify 產生 JSON,而不是複製其控制台表示形式。當您收到文字時,僅使用解析器解析其宣告的格式,而不要將其作為快捷方式執行。成功的 JSON 驗證建立的是語法,而不是數字精度、模式一致性或安全性的下游屬性處理。