چرا چینی به \u4e2d\u6587 تبدیل میشود
جمعبندی: escape بهصورت \u4e2d\u6587 یونیکد قانونی است، نه خرابی رمزگذاری. mojibake واقعی متفاوت به نظر میرسد و تشخیص این دو تعیین میکند واقعاً چه چیزی باید اصلاح شود.

جمعبندی: خروجی \uXXXX را escape قانونی بدانید، تأیید کنید که از JSON.parse رفتوبرگشت میکند، و وقتی چینی خوانا میخواهید سریالایز ASCII خالص مانند ensure_ascii=False را خاموش کنید؛ escape را فقط برای انتقالهایی نگه دارید که نمیتوانند غیر ASCII حمل کنند.
چون escape شده، نه اینکه آسیب دیده باشد.
JSON.parse('"\\u4e2d\\u6587"') // "中文"
\u4e2d همان 中 و \u6587 همان 文 است. اینها دنبالههای escape قانونیاند؛ هر پارسری بازیابیشان میکند. چیزی خراب نیست — فقط در لاگها، diffها و ضبط بسته ناخواناست.
چه کسی escape میکند
| ابزار | پیشفرض | کلید تغییر |
|---|---|---|
json.dumps در Python |
escape میکند (ensure_ascii=True) |
ensure_ascii=False |
JSON.stringify در جاوااسکریپت |
بدون escape | — |
| Jackson در Java | بدون escape | اختیاری |
json_encode در PHP |
از ۵.۴ بدون escape | — |
encoding/json در Go |
بدون escape | — |
Python تا اینجا رایجترین منبع است. پیشفرض دلیلی دارد: خروجی ASCII خالص از هر انتقالی جان سالم به در میبرد. هزینهاش این است که هر نویسه غیر ASCII به شش نویسه تبدیل میشود.
escape در برابر mojibake
escape: \u4e2d\u6587، مطابق \uXXXX. ناشی از تنظیمات سریالایزر.
mojibake: 测试، 涓枃. ناشی از نوشتن بایتهای UTF-8 و خواندنشان بهعنوان Latin-1 یا GBK.
آزمون سریع: متن را در کنسول مرورگر بهصورت JSON.parse('"…"') جایگذاری کنید. اگر خوانا برگشت، escape بوده. اگر شکست خورد یا متلاشی ماند، ناسازگاری رمزگذاری است — و اصلاحش همتراز کردن رمزگذاریهاست، نه دست زدن به سریالایزر.
خاموش کردنش
json.dumps(data, ensure_ascii=False)
سپس پاییندست را تأیید کنید: برخی سیستمهای قدیمی واقعاً به انتقال فقط ASCII تکیه میکنند، بهویژه دروازههای SMS و رلههای ایمیل قدیمیتر.
چه زمانی escape انتخاب درست است
- انتقالهایی که به غیر ASCII خصمانهاند (سرآیندهای HTTP قدیمی، برخی دروازههای SMS)
- JSON تودرتو داخل رشته JSON دیگر، که escape تعارض گیومه را کم میکند
- خطوط لاگ که بر اساس بایت کوتاه میکنند و نویسه چندبایتی را میشکنند
در غیر این صورت، خوانایی را ترجیح دهید و خاموشش کنید.
پرسشهای متداول
چرا Python بهصورت پیشفرض چینی را escape میکند؟
چون ensure_ascii=True پیشفرض است و خروجی ASCII خالص را تضمین میکند که از هر انتقالی جان سالم به در میبرد. هزینهاش این است که هر نویسه غیر ASCII به شش نویسه تبدیل میشود.
آیا باید ensure_ascii را خاموش کنم؟
وقتی خوانایی مهم است خاموشش کنید. سپس پاییندست را تأیید کنید — سرآیندهای HTTP قدیمی، برخی دروازههای SMS و خطوط لاگی که بر اساس بایت کوتاه میکنند ممکن است همچنان به محتوای فقط ASCII تکیه کنند.
اگر انتقال نتواند غیر ASCII حمل کند چه میشود؟
escape را نگه دارید. وقتی JSON داخل رشته JSON دیگری جاسازی میشود، یا از کانالی عبور میکند که به غیر ASCII خصمانه است، escape از تعارض گیومه جلوگیری میکند و مانع شکستن نویسههای چندبایتی میشود.