web-dev-qa-db-fra.com

Encodage de caractères JSON - UTF-8 est-il bien pris en charge par les navigateurs ou dois-je utiliser des séquences d'échappement numériques?

J'écris un service Web qui utilise JSON pour représenter ses ressources, et je suis un peu coincé à réfléchir au meilleur moyen de coder le json. En lisant le fichier json rfc ( http://www.ietf.org/rfc/rfc4627.txt ), il est clair que le codage préféré est utf-8. Mais le rfc décrit également un mécanisme d'échappement de chaîne pour spécifier des caractères. Je suppose que cela serait généralement utilisé pour échapper aux caractères non-ascii, rendant ainsi l'utci-uf-8 résultant.

Donc, disons que j'ai une chaîne JSON qui contient des caractères Unicode (points de code) qui ne sont pas ascii. Mon service Web devrait-il simplement coder cela en utf-8 et le renvoyer, ou devrait-il échapper à tous ces caractères non ascii et renvoyer un pur ascii?

J'aimerais que les navigateurs puissent exécuter les résultats en utilisant jsonp ou eval. Est-ce que cela affecte la décision? Ma connaissance du support javascript de divers navigateurs pour utf-8 manque.

EDIT: Je voulais préciser que ma principale préoccupation concernant la manière de coder les résultats concerne en réalité la gestion des résultats par un navigateur. Ce que j'ai lu indique que les navigateurs peuvent être sensibles au codage lors de l'utilisation de JSONP en particulier. Je n'ai trouvé aucune très bonne information sur le sujet, je vais donc devoir faire des tests pour voir ce qui se passe. Idéalement, j'aimerais seulement échapper aux quelques caractères requis et simplement utf-8 encoder les résultats.

77
schickb

La spécification JSON obligatoire Prise en charge UTF-8 par les décodeurs. En conséquence, tous les décodeurs JSON peuvent gérer UTF-8 aussi bien qu’ils peuvent gérer les séquences d’échappement numériques. C'est également le cas pour les interpréteurs Javascript, ce qui signifie que JSONP gérera également le JSON codé UTF-8.

La possibilité pour les encodeurs JSON d’utiliser les séquences d’échappement numériques à la place vous offre plus de choix. Une raison pour laquelle vous pouvez choisir les séquences d'échappement numériques serait si un mécanisme de transport entre les deux votre encodeur et le décodeur prévu n'est pas sécurisé en binaire.

Une autre raison pour laquelle vous pouvez utiliser des séquences d'échappement numériques est d'empêcher certains caractères d'apparaître dans le flux, tels que <, & et ", qui peut être interprété comme une séquence HTML si le code JSON est placé sans échapper à HTML ou si un navigateur l’interprète à tort comme HTML. Cela peut être une défense contre l’injection HTML ou le script intersite (note: certains caractères DOIVENT être échappés en JSON, y compris " et \).

Certains frameworks, y compris l'implémentation PHP de JSON, toujours font les séquences d'échappement numériques du côté encodeur pour tout caractère en dehors de l'ASCII. Ceci est destiné à une compatibilité maximale avec des mécanismes de transport limités et similaires. Toutefois, cela ne doit pas être interprété comme une indication que les décodeurs JSON ont un problème avec UTF-8.

Donc, je suppose que vous pourriez juste décider lequel utiliser comme ceci:

  • Utilisez simplement UTF-8, à moins que votre méthode de stockage ou de transport entre codeur et décodeur ne soit pas sécurisée en binaire.

  • Sinon, utilisez les séquences d'échappement numériques.

75
thomasrutter

J'ai eu un problème là-bas. Lorsque je JSON code une chaîne avec un caractère comme "é", tous les navigateurs renverront le même "é", à l'exception de IE qui renverra "\ u00e9".

Ensuite, avec PHP json_decode (), il échouera s'il trouve "é", donc pour Firefox, Opera, Safari et Chrome, je dois appeler utf8_encode () avant json_decode ().

Remarque: avec mes tests, IE et Firefox utilisent leur objet JSON natif, les autres navigateurs utilisent json2.js.

15
Olivier

ASCII n'y est plus. Utiliser l'encodage UTF-8 signifie que vous n'utilisez pas l'encodage ASCII. Ce que vous devriez utiliser comme mécanisme d'échappement, c'est ce que dit le RFC:

Tous les caractères Unicode peuvent être placés entre guillemets, à l'exception des caractères qui doivent être omis: guillemets, reverse solidus et les caractères de contrôle (U + 0000 à U + 001F).

12
chaos

Je faisais face au même problème. Ça marche pour moi. S'il te plaît, vérifie cela.

json_encode($array,JSON_UNESCAPED_UNICODE);
7
Ankit Sewadik

En lisant le fichier json rfc ( http://www.ietf.org/rfc/rfc4627.txt ), il est clair que le codage préféré est utf-8.

Pour info, la RFC 4627 n’est plus la spécification JSON officielle. Il était obsolète en 2014 par RFC 7159 , puis obsolète en 2017 par RFC 8259 , qui correspond aux spécifications actuelles.

Le RFC 8259 déclare:

8.1. Encodage de caractère

Le texte JSON échangé entre des systèmes ne faisant pas partie d'un écosystème fermé DOIT être codé à l'aide de UTF-8 [RFC3629] .

Les précédentes spécifications de JSON n’avaient pas nécessité l’utilisation de UTF-8 lors de la transmission de texte JSON. Cependant, la grande majorité des implémentations logicielles basées sur JSON ont choisi d'utiliser le codage UTF-8, dans la mesure où il s'agit du seul codage permettant d'atteindre l'interopérabilité.

Les implémentations NE DOIVENT PAS ajouter de marque d'ordre d'octet (U + FEFF) au début d'un texte JSON transmis en réseau. Dans l'intérêt de l'interopérabilité, les implémentations qui analysent les textes JSON PEUVENT ignorer la présence d'une marque d'ordre d'octet plutôt que de la traiter comme une erreur.

1
Remy Lebeau

J'ai eu un problème similaire avec écar ... Je pense que le commentaire "il est possible que le texte que vous alimentez ne soit pas au format UTF-8" est probablement proche de la marque ici. J'ai le sentiment que le classement par défaut dans mon cas était quelque chose d'autre jusqu'à ce que je réalise et que je passe à utf8 ... le problème est que les données étaient déjà là, donc je ne sais pas s'il convertit les données ou non lorsque je les ai modifiées, l'affichage s'affiche correctement dans mysql Table de travail. Le résultat final est que php ne codera pas les données en json, mais renvoie faux. Peu importe le navigateur que vous utilisez comme serveur à l'origine de mon problème, php n'analysera pas les données en utf8 si ce caractère est présent. Comme si je disais pas si c'est dû à la conversion du schéma en utf8 après que les données étaient présentes ou juste un bogue php. Dans ce cas, utilisez json_encode(utf8_encode($string));

0
Paul Smith