[解決済み】jQuery.parseJSONでJSONのシングルクォートがエスケープされているため、「無効なJSON」エラーが発生する。
質問
サーバへのリクエストは
jQuery.post()
で、サーバーはJSONオブジェクトを返しています(
{ "var": "value", ... }
). しかし、値のどれかにシングルクオート (適切にエスケープされており、たとえば
\'
) 、jQueryは、他の有効なJSON文字列をパースするのに失敗します。以下は、私が言いたいことの例です (
Chromeのコンソールで行う
):
data = "{ \"status\": \"success\", \"newHtml\": \"Hello \\\'x\" }";
eval("x = " + data); // { newHtml: "Hello 'x", status: "success" }
$.parseJSON(data); // Invalid JSON: { "status": "success", "newHtml": "Hello \'x" }
これって普通なんでしょうか?JSON経由で単一の引用符を適切に渡す方法はないのでしょうか?
解決方法は?
のステートマシン図によると JSONサイト エスケープされたダブルクォート文字のみが許可され、シングルクォート文字は許可されません。シングルクォート文字はエスケープする必要がありません。
更新情報
- ご興味のある方は、より詳しい情報をご覧ください。
Douglas Crockford氏は、JSON仕様が文字列内のシングルクォートのエスケープを許可しない理由について、特に述べていません。しかし、JSONに関する彼の議論の中で JavaScriptの付録E。良いところ と、彼は書いている。
<ブロッククオートJSONの設計目標は、最小限であること、移植性があること、テキストであること、そしてJavaScriptのサブセットであることでした。相互運用のために合意する必要が少なければ少ないほど、相互運用が容易になります。
つまり、すべてのJSON実装が合意しなければならないルールが1つ減るので、ダブルクォートを使った文字列の定義のみを許可することにしたのでしょう。その結果、文字列内のシングルクォート文字が、誤って文字列を終了させることは不可能になりました。なぜなら、定義上、文字列はダブルクォート文字によってのみ終了させることができるからです。したがって、正式な仕様では、一文字の引用符のエスケープを許可する必要はありません。
もう少し掘り下げると、クロックフォードの org.json Java用のJSONの実装は、より許容範囲が広いし が行います。 はシングルクオートキャラクタを許可します。
<ブロッククオート
toStringメソッドで生成されるテキストは、JSONの構文規則に厳密に従ったものです。コンストラクタは、受け入れるテキストについてより寛容です。
...
- 文字列は、'(シングルクォート)で引用することができます。
によって確認されます。
JSONTokener
のソースコードです。その
nextString
メソッドは、エスケープされたシングルクォート文字を受け入れ、ダブルクォート文字と同じように扱います。
public String nextString(char quote) throws JSONException {
char c;
StringBuffer sb = new StringBuffer();
for (;;) {
c = next();
switch (c) {
...
case '\\':
c = this.next();
switch (c) {
...
case '"':
case '\'':
case '\\':
case '/':
sb.append(c);
break;
...
メソッドの先頭には、情報提供のためのコメントがあります。
正式なJSON形式では、一重引用符で囲まれた文字列は認められませんが、実装では受け入れることができます。
そのため、シングルクォートを受け入れる実装もありますが、これに依存してはいけません。多くの一般的な実装はこの点で非常に厳しく、シングルクォートされた文字列やエスケープされたシングルクォートを含むJSONは拒否されるでしょう。
最後に、最初の質問と関連付けます。
jQuery.parseJSON
は、まずブラウザのネイティブJSONパーサーか、または、以下のようなロードされたライブラリを使用しようとします。
json2.js
の場合、jQueryのロジックはこのライブラリに基づいています。
JSON
が定義されていない場合)。したがって、jQueryは、その基礎となる実装と同じくらい寛容であることができます。
parseJSON: function( data ) {
...
// Attempt to parse using the native JSON parser first
if ( window.JSON && window.JSON.parse ) {
return window.JSON.parse( data );
}
...
jQuery.error( "Invalid JSON: " + data );
},
私の知る限り、これらの実装は公式のJSON仕様にのみ準拠しており、シングルクォートを受け付けないため、jQueryもそうなっています。
関連
-
JavaScriptの関数この指摘の問題を説明
-
vueネットワークリクエストソリューション ネイティブネットワークリクエストとjsネットワークリクエストライブラリ
-
VUEグローバルフィルターの概念と留意点、基本的な使い方
-
[解決済み】GETできない / Nodejsエラー
-
[解決済み】TypeErrorの解決方法。未定義またはヌルをオブジェクトに変換できない
-
[解決済み】TypeScript-のAngular Frameworkエラー - "exportAsがngFormに設定されたディレクティブはありません"
-
[解決済み】 env: node: macにそのようなファイルやディレクトリはありません
-
[解決済み】(Google Map API) Geocodeは以下の理由で成功しませんでした。REQUEST_DENIED
-
[解決済み] Chromeのsendrequestエラーです。TypeError: 循環構造をJSONに変換中
-
[解決済み] JSON:なぜフォワードスラッシュはエスケープされるのですか?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
fetch ネットワークリクエストラッパーの説明例
-
Vueはランニングライト形式のテキストを水平方向にスクロールする機能を実装している
-
vueディレクティブv-bindの使用と注意点
-
vueにおけるfilterの適用シーンについて解説します。
-
[解決済み】TypeErrorの解決方法。未定義またはヌルをオブジェクトに変換できない
-
nodejs unhandledPromiseRejectionWarning メッセージ
-
モジュールのビルドに失敗しました。Error: ENOENT: no such file or directory, scandir 'D:\.... \node_modules
-
JavaScriptのgetElementById、getElementsByTagNam、getElementsByClassNameの違いと使い方
-
[解決済み] String表現のDictionaryをDictionaryに変換する?
-
[解決済み】文字列のJSON配列はどのように表現するのですか?