Чому китайський текст перетворюється на \u4e2d\u6587
Головне: Escape-послідовність \u4e2d\u6587 — це законний Unicode, а не збій кодування. Справжні «кракозябри» виглядають інакше, і розрізнення їх вирішує, що вам насправді треба виправити.

Коротко: трактуйте вивід \uXXXX як законне екранування, підтвердьте, що він проходить туди-назад через JSON.parse, і вимкніть серіалізацію в чистому ASCII, як-от ensure_ascii=False, коли хочете читабельний китайський текст; зберігайте екранування лише для транспортів, що не можуть нести не-ASCII.
Бо його екрановано, а не пошкоджено.
JSON.parse('"\\u4e2d\\u6587"') // "中文"
\u4e2d — це 中, а \u6587 — 文. Це законні escape-послідовності; будь-який парсер їх відновлює. Ніщо не зламано — просто нечитабельно в логах, diff і перехопленнях пакетів.
Хто робить екранування
| Інструмент | Типово | Перемикач |
|---|---|---|
Python json.dumps |
Екранує (ensure_ascii=True) |
ensure_ascii=False |
JavaScript JSON.stringify |
Не екранує | — |
| Java Jackson | Не екранує | Необовʼязково |
PHP json_encode |
Не екранує з 5.4 | — |
Go encoding/json |
Не екранує | — |
Python — далеко найпоширеніше джерело. Типове значення існує з причини: вивід у чистому ASCII виживає в будь-якому транспорті. Ціна — кожен не-ASCII символ стає шістьма символами.
Екранування проти «кракозябр»
Екранування: \u4e2d\u6587, що відповідає \uXXXX. Спричинене налаштуваннями серіалізатора.
«Кракозябри»: 测试, 涓枃. Спричинені записом байтів UTF-8 і читанням їх як Latin-1 або GBK.
Швидкий тест: вставте текст у консоль браузера як JSON.parse('"…"'). Якщо він повертається читабельним, це було екранування. Якщо зазнає збою або лишається спотвореним, це невідповідність кодувань — і виправлення в узгодженні кодувань, а не в дотику до серіалізатора.
Як вимкнути
json.dumps(data, ensure_ascii=False)
Потім перевірте нижче за течією: деякі спадкові системи справді покладаються на транспорт лише з ASCII, зокрема SMS-шлюзи й старіші поштові ретранслятори.
Коли екранування — правильний вибір
- Транспорти, ворожі до не-ASCII (спадкові заголовки HTTP, деякі SMS-шлюзи)
- JSON, вкладений усередину іншого рядка JSON, де екранування зменшує конфлікти лапок
- Конвеєри логів, що обрізають за байтами й розрізали б багатобайтовий символ
Інакше надавайте перевагу читабельності й вимикайте його.
Часті питання
Чому Python типово екранує китайський текст?
Бо ensure_ascii=True — типове значення, що гарантує вивід у чистому ASCII, який виживає в будь-якому транспорті. Ціна — кожен не-ASCII символ стає шістьма символами.
Чи варто вимикати ensure_ascii?
Вимикайте, коли важлива читабельність. Потім перевірте нижче за течією — спадкові заголовки HTTP, деякі SMS-шлюзи й конвеєри логів, що обрізають за байтами, усе ще можуть покладатися на вміст лише з ASCII.
Що робити, якщо транспорт не може нести не-ASCII?
Зберігайте екранування. Коли JSON вбудований усередину іншого рядка JSON або подорожує каналом, ворожим до не-ASCII, екранування уникає конфліктів лапок і запобігає розрізанню багатобайтових символів.