54 votes

erreur d'analyse json avec des guillemets doubles

Un guillemet double, même s'il est échappé, provoque 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]);

Il y a une erreur d'analyse à cause des guillemets doubles (qui sont déjà échappés).
Même eval() ne fonctionnera pas ici.
Mais si je l'échappe avec des doubles barres obliques comme ceci :

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

alors cela fonctionne bien.
Pourquoi devons-nous utiliser le double slash ici en javascript ? Le problème est que PHP json_encode() permet d'échapper à un guillemet double par une simple barre oblique (comme ceci : \"show\" ) qui JSON.parse ne sera pas en mesure de l'analyser. Comment puis-je gérer cette situation ?

35voto

cube Points 1789

Le Javascript désencode ses chaînes de caractères et le json les désencode également. la première chaîne ( '{"result": ["lunch", "\"Show\""] }' ) est vu par l'analyseur json comme étant {"result": ["lunch", ""Show""] } parce que \" en javascript signifie " mais ne quitte pas la chaîne entre guillemets.

La deuxième chaîne '{"result": ["lunch", "\\\"Show\\\""] }' devient d'abord non encodé en {"result": ["lunch", "\"Show\""] } (et qui est correctement désencapsulé par json).

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

34voto

Jet Points 1062

Finalement, l'analyse de JSON utilise le même eval, donc il n'y a aucune différence lorsque vous leur donnez quelque chose avec une syntaxe incorrecte. Dans ce cas, vous devez échapper correctement vos guillemets en php, puis les échapper ainsi que leurs slashs d'échappement avec json_encode.

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

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

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

2 votes

Mais c'est quelque chose qui devrait être pris en charge par la fonction json_encode(). Pourquoi renvoie-t-elle quelque chose qui ne peut pas être correctement analysé par JSON.parse().

7 votes

Il ne s'agit pas d'un bogue dans json_encode (je suppose que c'est ce que vous vouliez dire). json_encode n'est pas destiné à créer des chaînes littérales JavaScript, il n'effectue donc pas l'échappement supplémentaire.

11voto

steven.yang Points 3231

Ce problème est causé par le double mécanisme d'échappement des chaînes de caractères : l'un provient de JS et l'autre de JSON.

Une combinaison du caractère backslash associé à un autre caractère suivant est utilisée pour représenter un caractère qui n'est pas représentable autrement 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 backlashes '\' dans l'interpréteur JavaScript.

Du point de vue de l'interprète JavaScript, il interprète il y a deux retours de bâton (\) comme chaque ' \\ sera interprétée comme une séquence "\".

Du point de vue de l'analyseur JSON. reçoit deux retours de bâton ( \\ ) et les règles d'échappement des chaînes JSON les analyseront comme un seul '\', qui est le résultat de la 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]);

10voto

Ólafur Waage Points 40104

Desde el docs

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

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

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

Je n'ai pas encore essayé.

1 votes

Vous utilisez une version de PHP antérieure à 5.3.0, comme l'indique la documentation.

0 votes

C'est la réponse, mais cela aurait dû être le comportement par défaut dès le départ.

3voto

theo Points 41

Éteindre magic_quotes_gpc en php.ini .

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X