JSON 工具箱

中文為什麼變成 \u4e2d\u6587

結論:\u4e2d\u6587 是合法的 Unicode 轉義,不是編碼錯誤。真正的亂碼是「测试」這種。分清楚兩者,才知道該改序列化設定還是改檔案編碼。

入門約 3 分鐘發佈於 2026-10-30更新於 2026-10-30
中文 Unicode 轉義與真正亂碼的區別

結論:看到 \uXXXX 先當作正常轉義,用 JSON.parse 試一次就能確認能否還原;要直接顯示漢字就關掉序列化端的純 ASCII 輸出(例如 ensure_ascii=False),只有傳輸通道不支援非 ASCII 時才保留轉義。

因為它被轉義了,不是壞了。

JSON.parse('"\\u4e2d\\u6587"')  // "中文"

\u4e2d 就是「中」,\u6587 是「文」。這兩串字元是 JSON 字串裡的合法轉義序列,解析器讀到就會還原。功能上不會出錯,只是日誌、抓包、程式碼評閱裡讀起來很痛苦。

誰在轉義

工具 預設行為 開關
Python json.dumps 轉義(ensure_ascii=True) ensure_ascii=False
JavaScript JSON.stringify 不轉義 無
Java Jackson 不轉義 可選開啟
PHP json_encode 不轉義(5.4+) —
Go encoding/json 不轉義 無

Python 是最高頻的來源。預設值有歷史原因:保證輸出是純 ASCII,任何環境都能安全傳輸,代價就是中文全變轉義串。

轉義 vs 亂碼,先分清楚

轉義:\u4e2d\u6587,形如 \uXXXX,每個漢字六個字元。原因:序列化設定。 亂碼:测试、涓枃。原因:位元組按 UTF-8 寫入,卻按 Latin-1 或 GBK 讀取。

判斷方法:把文字複製到瀏覽器主控台執行 JSON.parse('"貼上內容"'),能還原成正常中文就是轉義,還原不出來或直接報錯,就是編碼問題。亂碼的修法完全不同——要統一讀寫兩端的編碼。

想直接看到漢字

json.dumps(data, ensure_ascii=False)

改完記得確認下游沒問題:有些舊系統真的依賴純 ASCII 傳輸,尤其是走簡訊、郵件、舊版閘道的場景。

什麼時候該保留轉義

  • 傳輸通道對非 ASCII 不友善(舊版 HTTP 標頭、部分簡訊閘道)
  • 需要把 JSON 嵌進另一層 JSON 字串裡,轉義能少一層引號衝突
  • 日誌系統按位元組截斷,多位元組字元被切斷會產生非法序列

除此之外,可讀性優先,關掉轉義。

常見問題

為什麼 Python 預設會把中文轉成 \uXXXX?

因為 ensure_ascii=True 是預設值,保證輸出是純 ASCII,任何環境都能安全傳輸。代價是每個非 ASCII 字元變成六個字元。

要不要關掉 ensure_ascii?

可讀性優先時關掉。改完再確認下游:舊版 HTTP 標頭、部分簡訊閘道、按位元組截斷的日誌系統仍可能依賴純 ASCII。

傳輸通道不支援非 ASCII 時是否該保留轉義?

要。把 JSON 嵌進另一層 JSON 字串,或走對非 ASCII 不友善的通道時,轉義能減少引號衝突,也能避免多位元組字元被截斷。

延伸閱讀