web-dev-qa-db-fra.com

erreur d'analyse json avec guillemets doubles

Une citation double, même si échappé, génère une erreur d'analyse.
regardez le code ci-dessous

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

Cela génère une erreur d'analyse à cause des guillemets doubles (qui sont déjà échappés).
Même eval() ne fonctionnera pas ici.
Mais si je lui échappe avec des doubles barres comme ceci:

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

alors ça marche bien.
Pourquoi devons-nous utiliser la double barre oblique ici en javascript? Le problème est que la fonction PHP json_encode() échappe à un guillemet double avec une seule barre oblique (comme ceci: \"show\") Qui JSON.parse A gagné ' t être en mesure d'analyser. Comment gérer cette situation?

47
Varun

Enfin, l'analyse JSON utilise le même eval, donc il n'y a pas de différence lorsque vous leur donnez smth. avec une syntaxe incorrecte. Dans ce cas, vous devez échapper correctement vos citations en php, puis les échapper et leurs barres obliques avec json_encode

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

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

Cela devrait fonctionner sur JS côté client (si je n'ai fait aucune faute de frappe).

30
Jet

Javascript échappe ses chaînes et json les échappe également. la première chaîne ('{"result": ["lunch", "\"Show\""] }') est vu par l'analyseur json comme {"result": ["lunch", ""Show""] }, car \" en javascript signifie ", mais ne quitte pas la chaîne entre guillemets doubles.

La deuxième chaîne '{"result": ["lunch", "\\\"Show\\\""] }' obtient le premier échappé à {"result": ["lunch", "\"Show\""] } (et qui est correctement échappé par json).

Je pense que '{"result": ["lunch", "\\"Show\\""] }' devrait aussi fonctionner.

34
cube

Ce problème est dû au mécanisme d'échappement de chaîne à deux volets: l'un provient de JS et l'autre de JSON.

Une combinaison du caractère barre oblique inverse combinée avec un autre caractère suivant est utilisée pour représenter n caractère qui n'est pas autrement représentable dans la chaîne. '' \\ '' signifie '\' etc.

Ce mécanisme d'échappement a lieu avant que JSON.parse () ne fonctionne.

Par exemple,

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

Du point de vue du générateur de chaînes, il passe quatre contre-coups '\' dans l'interpréteur JavaScript.

Du point de vue de l'interpréteur JavaScript, il interprète il y a deux contre-coups (\) car chaque séquence '\\' sera interprétée comme un '\'.

Du point de vue de l'analyseur JSON, il reçoit deux contre-coups (\\) et les règles d'échappement de la chaîne JSON l'analyseront comme un seul '\' qui est le résultat de sortie.

Expliquez votre premier code:

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

Depuis docs

JSON_HEX_APOS (entier) Tous 'sont convertis en\u0027
JSON_HEX_QUOT (entier) Tous "sont convertis en\u0022

json_encode () prend deux arguments, la valeur et les options. Alors essayez

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

Je n'ai pas essayé ça cependant.

10
Ólafur Waage

Éteindre magic_quotes_gpc in php.ini.

3
theo

php en objet javascript (php> = 5.3.0)

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

Si les échappements C standard sont ajoutés, alors JSON.parse Convertira des séquences comme \" En ", \\ En \, \n Dans un saut de ligne, etc.

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

Dans le cas de notre projet:

chaîne d'origine ""{\"lat\":28.4594965,\"lng\":77.0266383}""

Après être passé à JSON.parse()

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

Le 2dakota du Nord passer à JSON.parse()

{lat: 28.4594965, lng: 77.0266383}

Notez que JSON.parse() a supprimé les caractères d'échappement au lieu de convertir string en object.

Après la suppression des caractères d'échappement, la conversion de chaîne en objet a fonctionné.

Voici la démo:

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

Cela pourrait aider:

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