Comment échapper des caractères spéciaux dans la construction d'une chaîne JSON?

200

Voici ma chaîne

{
    'user': {
        'name': 'abc',
        'fx': {
            'message': {
                'color': 'red'
            },
            'user': {
                'color': 'blue'
            }
        }
    },
    'timestamp': '2013-10-04T08: 10: 41+0100',
    'message': 'I'mABC..',
    'nanotime': '19993363098581330'
}    

Ici, le message contient un guillemet simple, identique à celui utilisé dans JSON. Ce que je fais est de remplir une chaîne à partir d'entrées utilisateur telles qu'un message. Donc, j'ai besoin d'échapper à ce genre de scénarios spéciaux qui cassent le code. Mais à part le remplacement de chaîne, existe-t-il un moyen de les faire échapper mais tout de même permettre à HTML de les renvoyer au bon message?

dinesh707
la source
45
JSON utilise uniquement des guillemets doubles, pas des guillemets simples, voir json.org
Niels Bom
4
La RFC 4627 stipule que les analyseurs doivent être capables d'analyser le JSON conforme (paragraphe 4) et peuvent prendre en charge des extensions non JSON supplémentaires. Cependant, le paragraphe 5 stipule clairement que tous les producteurs (producteurs) DOIVENT produire UNIQUEMENT du JSON 100% conforme. Produire du JSON avec des caractères de cadre qui n'ont pas besoin d'être échappés est une idée particulièrement mauvaise. Veuillez envisager de remplacer vos apostrophes par des guillemets. ietf.org/rfc/rfc4627.txt
Luv2code
3
@ Luv2code Alors que les points que vous faites restent vrais, notez que vous citez une spécification obsolète. Lors de la lecture des RFC, utilisez toujours la version tools.ietf.org/html , pas la version texte. Les versions HTML sont plus faciles à lire et à lier à des sous-sections de, et plus important encore, en haut des versions HTML se trouve une liste de tous les RFC ultérieurs qui mettent à jour ou obsolète celle que vous lisez. Si vous étiez allé sur tools.ietf.org/html/rfc4627, vous auriez vu que la RFC 4627 est obsolète et a été remplacée par la RFC 7159 .
Mark Amery
3
Pour les personnes qui liront ceci à l'avenir, la RFC 7159 a à son tour été obsolète par tools.ietf.org/html/rfc8259
Joram van den Boezem

Réponses:

286

Une chaîne JSON doit être placée entre guillemets, conformément aux spécifications , afin que vous n'ayez pas besoin de vous échapper '.
Si vous devez utiliser un caractère spécial dans votre chaîne JSON, vous pouvez l'échapper en utilisant\ caractère.

Voir cette liste de caractères spéciaux utilisés dans JSON:

\b  Backspace (ascii code 08)
\f  Form feed (ascii code 0C)
\n  New line
\r  Carriage return
\t  Tab
\"  Double quote
\\  Backslash character


Cependant, même si cela est totalement contraire à la spécification, l'auteur pourrait utiliser \'.

C'est mauvais parce que:

  • C'est contraire aux spécifications
  • Ce n'est plus une chaîne valide JSON

Mais cela fonctionne, que vous le vouliez ou non.

Pour les nouveaux lecteurs, utilisez toujours des guillemets doubles pour vos chaînes json.

AlexB
la source
30
"chaînes json entre guillemets simples" ? Ça n'a pas de sens; les chaînes en JSON ne peuvent jamais être mises entre guillemets. Essayez JSON.parse("'foo'")dans la console de votre navigateur, par exemple, et observez le SyntaxError: Unexpected token '. La spécification JSON est vraiment simple et claire à ce sujet. Il n'y a pas de séquence d'échappement dans JSON pour les guillemets simples, et une chaîne JSON ne peut pas être mise entre guillemets simples.
Mark Amery
15
Même la mise à jour censée clarifier cette réponse est mauvaise. Bien que techniquement vrai, il est trompeur de dire que vous "n'avez pas besoin" de vous échapper ', de la même manière que c'est techniquement vrai mais trompeur de dire que légalement vous n'avez pas besoin de tuer des enfants. Plus correct serait de dire que vous ne pouvez pas vous échapper '. \'est une séquence d'échappement illégale, et si vous l'utilisez, votre JSON n'est pas un JSON valide et tout analyseur JSON s'y étouffera. (Certainement JavaScript JSON.parseet Python le json.loadsfont.)
Mark Amery
2
Cette réponse reste totalement absurde après de nombreuses modifications. Vous prétendez, à tort, qu'utiliser des chaînes entre guillemets simples dans JSON et utiliser la \'séquence d'échappement "fonctionne, que vous le vouliez ou non" . C'est faux. Je vous mets au défi d'exposer tout analyseur JSON couramment utilisé qui ne s'étouffera pas avec les chaînes entre guillemets simples ou la \'séquence. J'ai déjà souligné que JSON.parse("'foo'")et JSON.parse('"\\\'"') (en JavaScript) et json.loads("'foo'")et json.loads('"\\\'"')(en Python) lèvent tous deux des exceptions. Quelle est la base de votre affirmation selon laquelle l'utilisation de ces constructions "fonctionne"?
Mark Amery
10
@ Luv2code citation intéressante. Vous l'avez mal interprété légèrement; cela ne signifie pas qu'un personnage peut être échappé simplement en mettant une barre oblique inverse devant lui. Une citation plus complète est "N'importe quel caractère peut être échappé. Si le caractère est dans le plan multilingue de base (U + 0000 à U + FFFF), alors il peut être représenté comme une séquence de six caractères . ... Alternativement, il y a deux -la séquence de caractères échappe aux représentations de certains personnages populaires. "(c'est moi qui souligne). Cela veut dire que vous pouvez vous échapper en 'tant que \u0027, non pas que vous pouvez y échapper en tant que \'.
Mark Amery
2
@ Luv2code encore, cela signifie que mon commentaire surévalué disant que "vous ne pouvez pas vous échapper '" (et en comparant un tel acte au meurtre d'enfants!) Est techniquement faux; plus précis est de dire que vous pouvez y échapper, tout simplement pas \'. Je ne m'étais pas rendu compte que la version RFC de la spécification faisait référence à des séquences comme \u0027un moyen d'échapper aux personnages qu'elles représentent. Le point clé qui \'est illégal, cependant, est toujours vrai et important.
Mark Amery
362

Je suis consterné par la présence de fausses informations très votées sur une question aussi bien vue sur un sujet fondamental.

Les chaînes JSON ne peuvent pas être entre guillemets simples . Les différentes versions de la spécification ( l'original par Douglas Crockford, la version ECMA et la version IETF ) indiquent toutes que les chaînes doivent être entre guillemets. Ce n'est pas une question théorique, ni une question d'opinion comme le suggère actuellement la réponse acceptée; tout analyseur JSON dans le monde réel affichera une erreur si vous essayez de le faire analyser une chaîne entre guillemets simples.

La version de Crockford et de l'ECMA affiche même la définition d'une chaîne à l'aide d'une jolie image, ce qui devrait clarifier le point sans ambiguïté:

Image montrant la définition d'une chaîne à partir de la spécification JSON

La jolie image répertorie également toutes les séquences d'échappement légitimes dans une chaîne JSON:

  • \"
  • \\
  • \/
  • \b
  • \f
  • \n
  • \r
  • \t
  • \u suivi de quatre chiffres hexadécimaux

Notez que, contrairement au non-sens dans certaines autres réponses ici, \' n'est jamais une séquence d'échappement valide dans une chaîne JSON. Ce n'est pas nécessaire, car les chaînes JSON sont toujours entre guillemets.

Enfin, vous ne devriez normalement pas avoir à penser à échapper des caractères vous-même lors de la génération par programme de JSON (bien sûr, vous le ferez lors de l'édition manuelle, par exemple, d'un fichier de configuration basé sur JSON). Au lieu de cela, formez la structure de données que vous souhaitez coder en utilisant les types de carte, tableau, chaîne, nombre, booléen et null natifs de votre langue, puis codez-les en JSON avec une fonction de codage JSON. Une telle fonction est probablement intégrée dans le langage que vous utilisez, comme JavaScript JSON.stringify, PHPjson_encode ou Python.json.dumps. Si vous utilisez un langage qui n'a pas une telle fonctionnalité intégrée, vous pouvez probablement trouver une bibliothèque d'analyse et de codage JSON à utiliser. Si vous utilisez simplement des fonctions de langage ou de bibliothèque pour convertir des éléments vers et depuis JSON, vous n'aurez même jamais besoin de connaître les règles d'échappement de JSON. C'est ce que le questionneur erroné aurait dû faire ici.

Mark Amery
la source
4 hex octets ou amuse - gueules ?
leetbacoon
36

Tout le monde parle de comment s'échapper 'dans un 'littéral de chaîne entre guillemets. Il y a un problème beaucoup plus important ici: les littéraux de chaîne entre guillemets simples ne sont pas des JSON valides . JSON est basé sur JavaScript, mais ce n'est pas la même chose. Si vous écrivez un objet littéral dans du code JavaScript, très bien; si vous avez réellement besoin de JSON, vous devez utiliser" .

Avec des chaînes entre guillemets doubles, vous n'aurez pas besoin d'échapper à la '. (Et si vous vouliez un littéral "dans la chaîne, vous l'utiliseriez \".)

David Knipe
la source
1
Salut, vous avez dit avec des chaînes entre guillemets doubles, vous n'aurez pas besoin d'échapper à la '. Par exemple, si ma valeur de chaîne est "Member's_id" : 4, dites-vous qu'elle n'a pas besoin d'être échappée? Apparemment, j'ai un problème où cela donne une erreur de mauvais codage: UTF-8 et il est lu comme Member�s. C'est un fichier json généré manuellement.
Shubham
1
'dans une chaîne JSON, le littéral ne doit pas être échappé. L'avez-vous copié-collé quelque part? C'est peut-être vraiment \u2019une apostrophe, pas une. Ma conjecture: quelqu'un l'a tapé dans MS Word, ce qui l'a transformé en guillemets parce qu'il pense qu'il sait mieux. Grammaticalement, le bon vieux apostrophe de caractère ASCII ( ', alias \x27, que nous appelions jusqu'à présent "guillemet simple") est celui que vous voulez. Mais il serait toujours bien de résoudre votre problème d'encodage de caractères, au cas où il y aurait d'autres problèmes similaires. Choisissez donc un codage de caractères et utilisez-le pour les lectures et les écritures. Ou échapper à l'aide \u.
David Knipe du
7

La plupart de ces réponses ne répondent pas à la question ou sont inutilement longues dans l'explication.

OK, JSON n'utilise que des guillemets doubles, nous comprenons!

J'essayais d'utiliser JQuery AJAX pour publier des données JSON sur le serveur, puis renvoyer plus tard ces mêmes informations. La meilleure solution à la question que j'ai trouvée était d'utiliser:

var d = {
    name: 'whatever',
    address: 'whatever',
    DOB: '01/01/2001'
}
$.ajax({
    type: "POST",
    url: 'some/url',
    dataType: 'json',
    data: JSON.stringify(d),
    ...
}

Cela échappera aux personnages pour vous.

Cela a également été suggéré par Mark Amery, Great answer BTW

J'espère que cela aide quelqu'un.

Déchirer, foutre une branlée
la source
0

Peut-être que je suis trop en retard pour la fête, mais cela analysera / échappera à une citation simple (je ne veux pas entrer dans une bataille sur l'analyse par rapport à l'évasion) ..

JSON.parse("\"'\"")
YankTHEcode
la source
0

La réponse à la question directe:
Pour être sûr, remplacez le caractère requis par \ u + valeur hexadécimale à 4 chiffres

Exemple: si vous voulez échapper à l'apostrophe, remplacez par \ u0027
D'Amico devient D \ u0027Amico

BELLE RÉFÉRENCE: http://es5.github.io/x7.html#x7.8.4

https://mathiasbynens.be/notes/javascript-escapes

Luigi D'Amico
la source
-1 pour les références. La question concerne JSON, mais vos références liées concernent JavaScript et répertorient les séquences d'échappement qui ne sont pas valides en JavaScript \'.
Mark Amery
Merci Mark - je voulais vraiment donner un angle alternatif - selon qui arrive ici peut trouver cela utile. Mais je prends votre point sur JSON et Javascript - Merci d'être un Ninja sur les forums.
Luigi D'Amico
0

Utilisez encodeURIComponent () pour coder la chaîne.

Par exemple. var product_list = encodeURIComponent (JSON.stringify (product_list));

Vous n'avez pas besoin de le décoder car le serveur Web fait automatiquement la même chose.

Sanju Kaniyamattam
la source
0

Utilisation des modèles de littéraux ...

var json = `{"1440167924916":{"id":1440167924916,"type":"text","content":"It's a test!"}}`;
Ruben
la source
-2

Je pense que nous sommes tous d'accord pour dire que les jsons simples ne sont pas de vrais jsons. Quoi qu'il en soit, nous devons encore aborder la question de l'échappement "dans une chaîne json entre guillemets doubles, en l'absence de bibliothèques pour le faire pour nous.

Remplacer chaque "par un \" NE SUFFIT PAS: L'utilisateur peut entrer l'entrée: \ et l'analyse, encore une fois, échoue (pensez pourquoi).

Au lieu de cela, remplacez d'abord chaque \ par \ (double barre oblique inverse). Seulement alors, remplacez chaque "par \" (barre oblique inverse suivie de ").

Tom Blitz
la source
-2

Pour autoriser les guillemets simples au sein de la chaîne entre guillemets dans le cadre de json, vous doublez le guillemet simple. {"X": "Quelle est la question"} ==> {"X": "Quelle est la question"}

/codereview/69266/json-conversion-to-single-quotes

La séquence \ 'n'est pas valide.

4T2G
la source
2
Le fait de doubler une seule citation dans une chaîne JSON n'y échappe pas. Cela signifie simplement que votre chaîne contient deux guillemets simples, au lieu d'un.
Mark Amery
-15

concernant le poste d'AlexB:

 \'  Apostrophe or single quote
 \"  Double quote

l'échappement des guillemets simples n'est valide que dans les chaînes json entre guillemets simples
échappement des guillemets doubles n'est valide que dans les chaînes json entre guillemets doubles

exemple:

'Bart\'s car'       -> valid
'Bart says \"Hi\"'  -> invalid
Bart
la source
14
Les chaînes entre guillemets simples ne sont pas légales dans JSON. JSON n'est pas javascript. JSON ne permet pas d'échapper au guillemet simple. Voir json.org pour le document très simple de la syntaxe JSON.
srm
3
downvote - parce que les guillemets simples ne sont pas valides!
DominikAngerer
Les guillemets simples ne sont pas valides dans json. Veuillez montrer un échantillon de travail si cela est possible
Rohith