Proč se čínština mění na \u4e2d\u6587
Shrnutí: Escape sekvence `\u4e2d\u6587` je legální Unicode, nikoli selhání kódování. Skutečný mojibake vypadá jinak a rozlišení rozhoduje o tom, co vlastně potřebujete opravit.

Stručně: výstup \uXXXX považujte za legální escapování, potvrďte, že projde obousměrným převodem přes JSON.parse, a když chcete čitelnou čínštinu, vypněte serializaci do čistého ASCII, například ensure_ascii=False; escapování ponechte jen pro přenosy, které neunesou non-ASCII.
Protože byl escapován, nikoli poškozen.
JSON.parse('"\\u4e2d\\u6587"') // "中文"
\u4e2d je 中 a \u6587 je 文. Jsou to legální escape sekvence; každý parser je obnoví. Nic není rozbité – jen to není čitelné v logech, diffech a odchytech paketů.
Kdo escapování provádí
| Nástroj | Výchozí | Přepínač |
|---|---|---|
Python json.dumps |
Escapuje (ensure_ascii=True) |
ensure_ascii=False |
JavaScript JSON.stringify |
Neescapuje | — |
| Java Jackson | Neescapuje | Volitelné |
PHP json_encode |
Neescapuje od 5.4 | — |
Go encoding/json |
Neescapuje | — |
Python je zdaleka nejčastější zdroj. Výchozí nastavení existuje z důvodu: výstup v čistém ASCII přežije jakýkoli přenos. Cenou je, že každý non-ASCII znak se stane šesti znaky.
Escapování versus mojibake
Escapování: \u4e2d\u6587, odpovídající \uXXXX. Způsobeno nastavením serializátoru.
Mojibake: 测试, 涓枃. Způsobeno zápisem bajtů UTF-8 a jejich čtením jako Latin-1 nebo GBK.
Rychlý test: vložte text do konzole prohlížeče jako JSON.parse('"…"'). Pokud se vrátí čitelný, šlo o escapování. Pokud selže nebo zůstane rozsypaný, jde o nesoulad kódování – a oprava je srovnat kódování, nikoli sahat na serializátor.
Vypnutí
json.dumps(data, ensure_ascii=False)
Poté ověřte downstream: některé legacy systémy skutečně spoléhají na přenos pouze v ASCII, zejména SMS brány a starší mailové relays.
Kdy je escapování správnou volbou
- Přenosy nepřátelské k non-ASCII (legacy HTTP hlavičky, některé SMS brány)
- JSON vnořený do jiného řetězce JSON, kde escapování snižuje konflikty uvozovek
- Logovací pipeline, které zkracují po bajtech a rozdělily by vícebajtový znak
Jinak preferujte čitelnost a vypněte ho.
Časté dotazy
Proč Python ve výchozím nastavení escapuje čínštinu?
Protože ensure_ascii=True je výchozí, což zaručuje výstup v čistém ASCII, který přežije jakýkoli přenos. Cenou je, že každý non-ASCII znak se stane šesti znaky.
Mám vypnout ensure_ascii?
Vypněte ho, když záleží na čitelnosti. Poté ověřte downstream – legacy HTTP hlavičky, některé SMS brány a logovací pipeline, které zkracují po bajtech, mohou stále spoléhat na obsah pouze v ASCII.
Co se stane, když přenos neunese non-ASCII?
Escapování ponechte. Když je JSON vnořen do jiného řetězce JSON nebo cestuje kanálem nepřátelským k non-ASCII, escapování zabraňuje konfliktům uvozovek a brání rozdělení vícebajtových znaků.