Tại sao tiếng Trung biến thành \u4e2d\u6587
Kết luận: Chuỗi escape \u4e2d\u6587 là Unicode hợp lệ, không phải lỗi encoding. Mojibake thật trông khác, và việc phân biệt hai trường hợp quyết định bạn thực sự cần sửa gì.

Tóm lại: hãy coi đầu ra \uXXXX là escape hợp lệ, xác nhận nó đi vòng qua JSON.parse được, và tắt tuần tự hóa ASCII thuần như ensure_ascii=False khi bạn muốn thấy tiếng Trung đọc được; chỉ giữ escape cho những kênh truyền không thể mang ký tự ngoài ASCII.
Vì nó bị escape, không phải bị hỏng.
JSON.parse('"\\u4e2d\\u6587"') // "中文"
\u4e2d là 中 và \u6587 là 文. Đây là các chuỗi escape hợp lệ; mọi trình phân tích đều khôi phục chúng. Không có gì hỏng — chỉ là nó khó đọc trong log, diff và bản bắt gói.
Ai thực hiện việc escape
| Công cụ | Mặc định | Cách tắt |
|---|---|---|
json.dumps của Python |
Escape (ensure_ascii=True) |
ensure_ascii=False |
JSON.stringify của JavaScript |
Không escape | — |
| Jackson của Java | Không escape | Tùy chọn |
json_encode của PHP |
Không escape từ 5.4 | — |
encoding/json của Go |
Không escape | — |
Python là nguồn phổ biến nhất, vượt trội. Mặc định đó có lý do: đầu ra ASCII thuần sống sót qua mọi kênh truyền. Cái giá là mỗi ký tự ngoài ASCII biến thành sáu ký tự.
Escape so với mojibake
Escape: \u4e2d\u6587, khớp mẫu \uXXXX. Do cấu hình bộ tuần tự hóa.
Mojibake: 测试, 涓枃. Do ghi byte UTF-8 rồi đọc chúng như Latin-1 hoặc GBK.
Phép thử nhanh: dán văn bản vào console trình duyệt dưới dạng JSON.parse('"…"'). Nếu nó trả về đọc được, đó là escape. Nếu nó thất bại hoặc vẫn bị rối, đó là encoding không khớp — và cách sửa là làm cho các encoding khớp nhau, không phải đụng vào bộ tuần tự hóa.
Tắt nó đi
json.dumps(data, ensure_ascii=False)
Sau đó hãy kiểm tra phía hạ nguồn: một số hệ thống cũ thực sự dựa vào việc truyền ASCII thuần, đặc biệt là gateway SMS và các máy chủ chuyển tiếp mail cũ.
Khi nào escape là lựa chọn đúng
- Những kênh truyền không thân thiện với ký tự ngoài ASCII (HTTP header cũ, một số gateway SMS)
- JSON được lồng bên trong một chuỗi JSON khác, nơi escape giúp giảm xung đột nháy
- Đường ống log cắt theo byte và có thể tách đôi một ký tự nhiều byte
Ngoài những trường hợp đó, hãy ưu tiên độ dễ đọc và tắt escape.
Hỏi đáp
Tại sao Python mặc định escape tiếng Trung?
Vì ensure_ascii=True là mặc định, đảm bảo đầu ra ASCII thuần sống sót qua mọi kênh truyền. Cái giá là mỗi ký tự ngoài ASCII biến thành sáu ký tự.
Có nên tắt ensure_ascii không?
Hãy tắt khi độ dễ đọc quan trọng. Sau đó kiểm tra phía hạ nguồn — HTTP header cũ, một số gateway SMS và đường ống log cắt theo byte vẫn có thể dựa vào nội dung chỉ chứa ASCII.
Điều gì xảy ra nếu kênh truyền không mang được ký tự ngoài ASCII?
Hãy giữ escape. Khi JSON được nhúng bên trong một chuỗi JSON khác, hoặc đi qua một kênh không thân thiện với ký tự ngoài ASCII, escape giúp tránh xung đột nháy và ngăn ký tự nhiều byte bị tách đôi.