JSON Toolkit

日本語が \u4e2d\u6587 になる理由

要点:\u4e2d\u6587 のエスケープは正当な Unicode で、エンコーディング障害ではありません。本当の文字化けは見た目が違い、両者を見分けることが何を直すべきかを決めます。

初級約 3 分で読めます2026-10-30 公開2026-10-30 更新
JSON における Unicode エスケープと本物の文字化けの違い

要点:\uXXXX の出力は正当なエスケープとして扱い、JSON.parse で往復することを確認し、読める日本語が欲しいときは ensure_ascii=False のような純 ASCII シリアライズを切りましょう。非 ASCII を運べない転送に限ってエスケープを保ちます。

エスケープされたのであって、壊れたのではありません。

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

\u4e2d は中、\u6587 は文です。これらは正当なエスケープシーケンスで、どのパーサーも復元します。壊れているものは何もなく、ログ、差分、パケットキャプチャで読めないだけです。

誰がエスケープするか

ツール 既定 切り替え
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 文字が 6 文字になることです。

エスケープと文字化け

エスケープ:\u4e2d\u6587、\uXXXX に一致。シリアライザ設定が原因。 文字化け:测试、涓枃。UTF-8 バイトを書いて Latin-1 や GBK として読むことが原因。

簡単なテスト:テキストをブラウザコンソールで JSON.parse('"…"') として貼ります。読める形で戻ればエスケープでした。失敗するか文字化けしたままならエンコーディングの不一致で、修正はエンコーディングを揃えることで、シリアライザには触れません。

切り方を知る

json.dumps(data, ensure_ascii=False)

そのうえで下流を検証します。一部のレガシーシステムは本当に ASCII のみの転送に依存しています。特に SMS ゲートウェイや古いメールリレーです。

エスケープが正しい選択であるとき

  • 非 ASCII に敵対的な転送(レガシー HTTP ヘッダー、一部の SMS ゲートウェイ)
  • 別の JSON 文字列の中にネストされた JSON。エスケープが引用符の衝突を減らします
  • バイト単位で切り詰め、マルチバイト文字を分割してしまうログパイプライン

それ以外では可読性を優先し、切ってください。

FAQ

Python が既定で日本語をエスケープするのはなぜですか?

ensure_ascii=True が既定で、どの転送でも生き残る純 ASCII 出力を保証するからです。代償はすべての非 ASCII 文字が 6 文字になることです。

ensure_ascii を切るべきですか?

可読性が重要なときは切ります。そのうえで下流を検証してください。レガシー HTTP ヘッダー、一部の SMS ゲートウェイ、バイト単位で切り詰めるログパイプラインは、ASCII のみの内容に依存しているかもしれません。

転送が非 ASCII を運べない場合はどうなりますか?

エスケープを保ちます。JSON が別の JSON 文字列の中に埋め込まれるとき、または非 ASCII に敵対的なチャネルを通るとき、エスケープは引用符の衝突を避け、マルチバイト文字の分割を防ぎます。

さらに読む