將 JSON 跳脫為字串字面值(並解碼被雙重編碼的 JSON)

對 JSON 進行 stringify 時,會用雙引號包裹並跳脫內部引號與特殊字元,得到一個可以安全嵌入到別處的 JSON 字串字面值。

「轉義成字面值」是什麼意思

把一個 JSON 字串傳給 JSON.stringify,它會用雙引號包起來,並對內部的引號與反斜線做跳脫,得到一個可以安全嵌入的單一字串值。

什麼時候需要它

把 JSON 嵌入到另一份 JSON 的欄位裡、存到字串型別的資料庫欄位,或當作環境變數或 URL 參數傳遞時,都需要先做成跳脫過的字串字面值。

跳脫規則

雙引號用反斜線跳脫,反斜線加倍,換行與 tab 等控制字元變成它們的兩字元跳脫序列。結果裡不會有原始的換行。

解碼雙重編碼的 JSON

如果收到一段以跳脫引號開頭、裡面含有跳脫引號序列的字串,代表它被 stringify 過了。先 parse 一次拿回內部的 JSON 字串,再 parse 一次才會得到真正的值。

雙重編碼會在哪裡冒出來

把 context 物件序列化的日誌框架、把 JSON body 包在 'body' 欄位裡的 webhook、用「JSON 字串信封」傳遞訊息的佇列,以及型別為 text 或 varchar 的資料庫欄位,都是最常見的來源。看到開頭一個引號加上偶數個反斜線就是訊號。

在日誌裡處理內嵌的 JSON

結構化日誌通常會把物件 stringify 成一行。要看的時候,把那一行從日誌檢視器裡複製出來,用 JSON.parse 把跳脫拆掉,再把還原出來的 JSON 格式化。不要對多行 JSON 物件做 grep —— stringify 成一行的 JSON 容易搜尋多了。

完成往返的工具

瀏覽器主控台:JSON.parse(line) 拿回內部 JSON,再 JSON.stringify(...,null,2) 美化。Node 命令列:'node -e "console.log(JSON.parse(process.argv[1]))" "<line>"' 一次到位。本站的 JSON Stringify 工具可以一鍵處理任意深度的巢狀。