web-dev-qa-db-ja.com

二重引用符付きのJSON解析エラー

エスケープされていても二重引用符が解析エラーを投げています。
以下のコードを見てください

_//parse the json in javascript  
var testJson = '{"result": ["lunch", "\"Show\""] }';  
var tags = JSON.parse(testJson);  
alert (tags.result[1]);
_

これは、二重引用符(既にエスケープされている)のために解析エラーをスローしています。
eval()でもここでは機能しません。
しかし、次のように二重スラッシュでエスケープすると:

_var result = '{"result": ["lunch", "\\"Show\\""] }';  
var tags = JSON.parse(result);  
alert (tags.result[1]);
_

その後、正常に動作します。
Javascriptで二重スラッシュを使用する必要があるのはなぜですか?問題は、PHP json_encode()関数が単一のスラッシュで二重引用符をエスケープすることです(このような:_\"show\"_)これは_JSON.parse_にはなりません)この状況をどのように処理しますか?

47
Varun

最後に、JSONの解析では同じevalが使用されるため、smthを指定しても違いはありません。構文が正しくありません。この場合、引用符をPHPで正しくエスケープしてから、json_encodeでエスケープしてスラッシュをエスケープする必要があります

<?php
    $json = '{"result": ["lunch", "\"Show\""] }';
    echo json_encode($json);
?>

OUTPUT: "{\"result\": [\"lunch\", \"\\\"Show\\\"\"] }"

これは、クライアント側のJSで機能するはずです(タイプミスがない場合)。

30
Jet

Javascriptは文字列をエスケープ解除し、jsonも文字列をエスケープ解除します。最初の文字列('{"result": ["lunch", "\"Show\""] }')はjsonパーサーから{"result": ["lunch", ""Show""] }として認識されます。これは、javascriptの\""を意味するが、二重引用符で囲まれた文字列を終了しないためです。

2番目の文字列'{"result": ["lunch", "\\\"Show\\\""] }'は、最初に{"result": ["lunch", "\"Show\""] }にエスケープ解除されます(jsonによって正しくエスケープ解除されます)。

'{"result": ["lunch", "\\"Show\\""] }'も機能するはずだと思います。

34
cube

この問題は、2つ折りの文字列エスケープメカニズムが原因で発生します。1つはJSに由来し、もう1つはJSONに由来します。

バックスラッシュ文字と別の後続の文字の組み合わせは、文字列内では表現できない1文字を表すために使用されます。 「\\」は「\」などを表します。

このエスケープメカニズムは、JSON.parse()が機能する前に行われます。

例えば、

var parsedObj = JSON.parse('{"sentence": "It is one backslash(\\\\)"}');
console.log(parsedObj.sentence);
>>>"It is one backslash(\)"

文字列ジェネレーターの観点からは、4つのバックラッシを渡す '\'をJavaScriptインタープリターに渡します。

JavaScriptインタープリターの観点からは、各「\\」シーケンスが1つの「\」として解釈されるため、2つのバックラッシュがあります(\)と解釈されます。

JSONパーサーの観点からは、2つのバックラッシュを受け取ります(\\)であり、JSON文字列エスケープルールは、出力結果である1つの「\」として解析します。

最初のコードを説明してください:

var testJson = '{"result": ["lunch", "\"Show\""] }';
//The real string after sequence escaping in to JS is
//'{"result": ["lunch", ""Show""] }' 
//which is passed into the JSON.parse.
//Thus, it breaks the JSON grammar and generates an error
var tags = JSON.parse(testJson);  
alert (tags.result[1]);
11
steveyang

docs から

JSON_HEX_APOS(整数)すべて 'は\ u0027に変換されます
JSON_HEX_QUOT(整数)すべて "は\ u0022に変換されます

json_encode()は、値とオプションの2つの引数を取ります。だから試して

json_encode($result, JSON_HEX_QUOT); // or
json_encode($result, JSON_HEX_QUOT | JSON_HEX_APOS);

しかし、私はこれを試していません。

10
Ólafur Waage

消す magic_quotes_gpc in php.ini

3
theo

phpからjavascriptオブジェクト(php> = 5.3.0)

var storesLocations = JSON.parse('<?php echo addslashes(json_encode($storesLocations,JSON_HEX_APOS | JSON_HEX_QUOT)) ?>');
2
valir

標準のCエスケープが追加された場合、_JSON.parse_は_\"_のようなシーケンスを_"_に、_\\_を_\_に、_\n_を行に変換します-フィードなど.

_'foo\\bar\nbaz"' === JSON.parse('"foo\\\\bar\\nbaz\\""')
_

私たちのプロジェクトの場合:

元の文字列_""{\"lat\":28.4594965,\"lng\":77.0266383}""_

JSON.parse()に渡した後

_"{"lat":28.4594965,"lng":77.0266383}"
_

に2nd JSON.parse()に渡す

_{lat: 28.4594965, lng: 77.0266383}
_

JSON.parse()は、stringobjectに変換する代わりにエスケープ文字を削除したことに注意してください。

エスケープ文字が削除された後、文字列からオブジェクトへの変換は機能しました。

デモは次のとおりです。

_while (typeof p1 != 'object') {
  p1 = JSON.parse(p1);
  pass++;
  console.log('On pass ', pass, p1);
}
_
0
student

これは役立つかもしれません:

<?php
$json = '{"result": ["lunch", "\"Show\""] }';
echo addslashes(json_encode($json));
0
Shahroq