web-dev-qa-db-ja.com

JSONとエスケープ文字

JavascriptでJSONにシリアル化され、Javaに逆シリアル化される文字列があります。

文字列に度数記号が含まれている場合、問題が発生します。

誰が責任を負うのかを理解するのにいくつかの助けを使うことができます:

  • spidermonkey 1.8の実装ですか? (これにはJSON実装が組み込まれています)
  • Google gson
  • 何かを適切に行わなかったのは私ですか?

JSDBで行われる処理は次のとおりです。

_js>s='15\u00f8C'
15°C
js>JSON.stringify(s)
"15°C"
_

_"15\u00f8C'_を期待していたので、SpidermonkeyのJSON実装は正しいことをしていないと思うようになります... JSONホームページの構文の説明 (仕様ですか?)文字ができること

ユニコード文字を除く「-または-\-または-制御文字」

したがって、\ u00f8としてエンコードせずに文字列をそのまま渡すことができます。この場合、問題はgsonライブラリにあると思われます。

誰でも助けることができますか?

私の回避策は別のJSONライブラリを使用するか、JSON.stringify()を呼び出した後に文字列を手動でエスケープすることですが、これがバグの場合はバグレポートを提出したいと思います。

51
Jason S

これは、どちらの実装のバグでもありません。 U + 00B0をエスケープする必要はありません。 [〜#〜] rfc [〜#〜] を引用するには:

2.5。文字列

文字列の表現は、プログラミング言語のCファミリで使用される規則に似ています。文字列は引用符で始まり、引用符で終わります。エスケープする必要がある文字を除くすべてのUnicode文字は、引用符で囲むことができます:引用符、逆ソリッド、および制御文字(U + 0000からU + 001F)。

任意の文字をエスケープできます

すべてをエスケープすると、データのサイズが大きくなります(すべてのコード変換ポイントは、すべてのUnicode変換形式で4バイト以下で表現できますが、エンコードするとすべて6バイトまたは12バイトになります)。

コードのどこかにテキストトランスコーディングのバグがある可能性が高く、ASCIIサブセットですべてをエスケープすると、すべてのデータがUnicodeエンコーディングを使用することがJSON仕様の要件です。 。

70
McDowell

うーん、とにかくここに回避策があります:

function JSON_stringify(s, emit_unicode)
{
   var json = JSON.stringify(s);
   return emit_unicode ? json : json.replace(/[\u007f-\uffff]/g,
      function(c) { 
        return '\\u'+('0000'+c.charCodeAt(0).toString(16)).slice(-4);
      }
   );
}

テストケース:

js>s='15\u00f8C 3\u0111';
15°C 3◄
js>JSON_stringify(s, true)
"15°C 3◄"
js>JSON_stringify(s, false)
"15\u00f8C 3\u0111"
70
Jason S