web-dev-qa-db-ja.com

JSON文字エンコード-UTF-8はブラウザーで十分にサポートされていますか、または数値エスケープシーケンスを使用する必要がありますか?

私はjsonを使用してそのリソースを表現するWebサービスを書いていますが、jsonをエンコードする最良の方法について少し考えていません。 json rfc( http://www.ietf.org/rfc/rfc4627.txt )を読むと、優先エンコードがutf-8であることは明らかです。しかし、rfcは、文字を指定するための文字列エスケープメカニズムについても説明しています。これは一般に非ASCII文字をエスケープするために使用され、それによって結果のutf-8が有効なasciiになると思います。

したがって、非ASCII文字であるUnicode文字(コードポイント)を含むjson文字列があるとします。私のウェブサービスはそれをUTF-8でエンコードして返す必要がありますか、それともすべての非ASCII文字をエスケープして純粋なASCIIを返す必要がありますか?

ブラウザでjsonpまたはevalを使用して結果を実行できるようにしたいと思います。それは決定に影響しますか?さまざまなブラウザのutf-8のjavascriptサポートに関する知識が不足しています。

編集:結果をエンコードする方法に関する私の主な関心は、実際に結果のブラウザ処理に関するものであることを明確にしたかったのです。私が読んだことは、特にJSONPを使用する場合、ブラウザーがエンコードに敏感であることを示しています。私はこの主題に関する本当に良い情報を見つけていないので、何が起こるかを見るためにいくつかのテストを始めなければなりません。理想的には、必要な少数の文字のみをエスケープし、utf-8だけで結果をエンコードしたいと思います。

77
schickb

JSON仕様必須デコーダーによるUTF-8サポート。その結果、すべてのJSONデコーダーは、数値エスケープシーケンスを処理できるだけでなく、UTF-8も処理できます。これはJavascriptインタープリターにも当てはまります。つまり、JSONPはUTF-8でエンコードされたJSONも処理します。

JSONエンコーダーが代わりに数値エスケープシーケンスを使用する機能は、より多くの選択肢を提供します。数値エスケープシーケンスを選択できる理由の1つは、トランスポートメカニズムの間エンコーダーと目的のデコーダーがバイナリセーフでない場合です。

数値エスケープシーケンスを使用するもう1つの理由は、<&"などの特定の文字がストリームに表示されないようにすることです。 HTMLとして。これは、HTMLインジェクションまたはクロスサイトスクリプティングに対する防御になります(注:JSONでは、"\など、一部の文字をエスケープする必要があります)。

JSONのPHP実装を含む一部のフレームワークでは、always ASCII以外の文字に対してエンコーダー側で数値エスケープシーケンスを実行します。これは、制限されたトランスポートメカニズムなどとの最大の互換性を目的としています。ただし、これはJSONデコーダーがUTF-8に問題があることを示すものとして解釈されるべきではありません。

したがって、次のようにどちらを使用するかを決定できると思います。

  • エンコーダとデコーダ間のストレージまたはトランスポートの方法がバイナリセーフでない場合を除き、UTF-8を使用してください。

  • それ以外の場合は、数値エスケープシーケンスを使用します。

75
thomasrutter

そこで問題がありました。 「é」のような文字を使用して文字列をJSONエンコードすると、すべてのブラウザーは「\ u00e9」を返すIEを除き、同じ「é」を返します。

次に、PHP json_decode()で「é」が見つかると失敗するため、Firefox、Opera、Safari、Chromeでは、json_decode()の前にutf8_encode()を呼び出す必要があります。

注:私のテストでは、IEとFirefoxはネイティブJSONオブジェクトを使用していますが、他のブラウザーはjson2.jsを使用しています。

15
Olivier

ASCIIはもう含まれていません。 UTF-8エンコーディングを使用すると、ASCIIエンコーディングを使用しないことになります。エスケープメカニズムを使用する必要があるのは、RFCの説明です。

エスケープする必要がある文字を除くすべてのUnicode文字を引用符で囲むことができます:引用符、逆ソリッド、および制御文字(U + 0000からU + 001F)

12
chaos

私は同じ問題に直面していました。わたしにはできる。これを確認してください。

json_encode($array,JSON_UNESCAPED_UNICODE);
7
Ankit Sewadik

Json rfc( http://www.ietf.org/rfc/rfc4627.txt )を読むと、優先エンコードがutf-8であることは明らかです。

参考までに、RFC 4627は公式のJSON仕様ではなくなりました。 2014年に RFC 7159 で廃止され、2017年に RFC 8259 で廃止されました。これは現在の仕様です。

RFC 8259の状態:

8.1。文字コード

閉じたエコシステムの一部ではないシステム間で交換されるJSONテキストは、UTF-8 [RFC3629]を使用してエンコードする必要があります。

JSONの以前の仕様では、JSONテキストを送信するときにUTF-8を使用する必要はありませんでした。ただし、JSONベースのソフトウェア実装の大部分は、相互運用性を実現する唯一のエンコーディングである限り、UTF-8エンコーディングの使用を選択しています。

実装は、ネットワーク送信されたJSONテキストの先頭にバイト順マーク(U + FEFF)を追加してはなりません。相互運用性のために、JSONテキストを解析する実装は、エラーとして扱うのではなく、バイトオーダーマークの存在を無視してもよい(MAY)。

1
Remy Lebeau

私はécharで同様の問題を抱えていました...「フィードしているテキストがUTF-8ではない可能性がある」というコメントは、おそらくここのマークに近いと思います。私のインスタンスのデフォルトの照合は、utf8に気付いて変更するまで別のものであると感じています...問題はデータがすでに存在しているため、変更したときにデータを変換したかどうかがわからず、mysqlでうまく表示されますワークベンチ。最終結果として、phpはデータをjsonエンコードせず、単にfalseを返します。私の問題を引き起こしているサーバーとして使用しているブラウザは関係ありませんが、この文字が存在する場合、phpはutf8へのデータを解析しません。私が言ったように、データが存在した後にスキーマをutf8に変換することに起因するのか、単にphpバグに起因するのかわからないという。この場合、json_encode(utf8_encode($string));を使用します

0
Paul Smith