JSON Toolkit

Dlaczego chiński zamienia się w \u4e2d\u6587

Podsumowanie: Sekwencja ucieczki \u4e2d\u6587 to legalny Unicode, a nie awaria kodowania. Prawdziwy mojibake wygląda inaczej, a rozróżnienie ich decyduje, co naprawdę trzeba naprawić.

Początkujący~3 min czytaniaOpublikowano 2026-10-30Zaktualizowano 2026-10-30
Ucieczka Unicode a prawdziwy mojibake w JSON

Najważniejsze: traktuj wyjście \uXXXX jako legalną ucieczkę, potwierdź, że przechodzi w obie strony przez JSON.parse, i wyłącz serializację czysto ASCII, taką jak ensure_ascii=False, gdy chcesz czytelnego chińskiego; zachowaj ucieczkę tylko dla transportów, które nie potrafią nieść nie-ASCII.

Bo został escape'owany, a nie uszkodzony.

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

\u4e2d to 中, a \u6587 to 文. To legalne sekwencje ucieczki; każdy parser je przywraca. Nic nie jest zepsute — jest tylko nieczytelne w logach, diffach i przechwyconym ruchu.

Kto wykonuje ucieczkę

Narzędzie Domyślnie Przełącznik
Python json.dumps Escape'uje (ensure_ascii=True) ensure_ascii=False
JavaScript JSON.stringify Nie escape'uje —
Java Jackson Nie escape'uje Opcjonalne
PHP json_encode Nie escape'uje od 5.4 —
Go encoding/json Nie escape'uje —

Python jest zdecydowanie najczęstszym źródłem. Domyślność istnieje nie bez powodu: wyjście czysto ASCII przetrwa każdy transport. Kosztem jest to, że każdy znak nie-ASCII staje się sześcioma znakami.

Ucieczka a mojibake

Ucieczka: \u4e2d\u6587, pasujące do \uXXXX. Spowodowane ustawieniami serializatora. Mojibake: 测试, 涓枃. Spowodowane zapisaniem bajtów UTF-8 i odczytaniem ich jako Latin-1 lub GBK.

Szybki test: wklej tekst do konsoli przeglądarki jako JSON.parse('"…"'). Jeśli wraca czytelnie, to była ucieczka. Jeśli zawodzi lub pozostaje zniekształcone, to niezgodność kodowań — a poprawką jest wyrównanie kodowań, a nie dotykanie serializatora.

Wyłączanie jej

json.dumps(data, ensure_ascii=False)

Potem zweryfikuj downstream: niektóre odziedziczone systemy naprawdę polegają na transporcie wyłącznie ASCII, zwłaszcza bramki SMS i starsze przekaźniki mailowe.

Kiedy ucieczka jest właściwym wyborem

  • Transporty wrogie wobec nie-ASCII (odziedziczone nagłówki HTTP, część bramek SMS)
  • JSON osadzony w innym łańcuchu JSON, gdzie ucieczka redukuje konflikty cudzysłowów
  • Potoki logów obcinające po bajtach, które podzieliłyby znak wielobajtowy

Poza tym preferuj czytelność i wyłącz ją.

FAQ

Dlaczego Python domyślnie escape'uje chiński?

Bo ensure_ascii=True jest domyślne, co gwarantuje wyjście czysto ASCII, które przetrwa każdy transport. Kosztem jest to, że każdy znak nie-ASCII staje się sześcioma znakami.

Czy wyłączać ensure_ascii?

Wyłącz, gdy liczy się czytelność. Potem zweryfikuj downstream — odziedziczone nagłówki HTTP, część bramek SMS i potoki logów obcinające po bajtach mogą nadal polegać na treści wyłącznie ASCII.

Co jeśli transport nie potrafi nieść nie-ASCII?

Zachowaj ucieczkę. Gdy JSON jest osadzony w innym łańcuchu JSON albo podróżuje kanałem wrogim wobec nie-ASCII, ucieczka unika konfliktów cudzysłowów i zapobiega podziałowi znaków wielobajtowych.

Dodatkowe materiały