325 votes

Que signifie réellement "Content-type : application/json ; charset=utf-8" ?

Lorsque je fais une demande POST avec un corps JSON à mon service REST, j'inclus Content-type: application/json; charset=utf-8 dans l'en-tête du message. Sans cet en-tête, je reçois une erreur du service. Je peux également utiliser avec succès Content-type: application/json sans le ;charset=utf-8 portion.

Que fait exactement charset=utf-8 faire ? Je sais qu'il spécifie le codage des caractères, mais le service fonctionne bien sans cela. Cet encodage limite-t-il les caractères qui peuvent figurer dans le corps du message ?

5 votes

Jeter un coup d'œil à hanselman.com/blog/

11 votes

De manière intrigante, selon L'IANA application/json Enregistrement du type de média il ne semble pas qu'il y ait un support charset bien qu'il soit souvent fourni dans la pratique.

1 votes

I know it specifies the character encoding but the service works fine without it. "fonctionner" ne signifie pas toujours "le code/la configuration existant(e) est la manière la plus correcte, couvrant tous les cas de figure, de faire une chose". Cela dépend de toutes les conventions et hypothèses qui peuvent ne pas fonctionner dans d'autres circonstances. Personnellement, j'essaie toujours d'être aussi explicite que possible.

320voto

deceze Points 200115

L'en-tête indique simplement en quoi le contenu est codé. Il n'est pas nécessairement possible de déduire le type de contenu à partir du contenu lui-même, c'est-à-dire qu'il ne suffit pas de regarder le contenu pour savoir ce qu'il faut en faire. C'est à cela que servent les en-têtes HTTP, qui indiquent au destinataire le type de contenu auquel il est (supposé) avoir affaire.

Content-type: application/json; charset=utf-8 indique que le contenu doit être au format JSON, codé avec le code de caractères UTF-8. Désigner l'encodage est quelque peu redondant pour JSON, puisque l'encodage par défaut (unique ?) pour JSON est UTF-8. Dans ce cas, le serveur récepteur est apparemment satisfait de savoir qu'il a affaire à JSON et suppose que l'encodage est UTF-8 par défaut, c'est pourquoi il fonctionne avec ou sans l'en-tête.

Cet encodage limite-t-il les caractères qui peuvent figurer dans le corps du message ?

Non. Vous pouvez envoyer ce que vous voulez dans l'en-tête et le corps. Mais, si les deux ne correspondent pas, vous risquez d'obtenir des résultats erronés. Si vous spécifiez dans l'en-tête que le contenu est codé en UTF-8 mais que vous envoyez en réalité un contenu codé en Latin1, le récepteur peut produire des données erronées en essayant d'interpréter des données codées en Latin1 comme étant des données UTF-8. Si, bien sûr, vous spécifiez que vous envoyez des données codées en Latin1 et que vous le faites réellement, alors oui, vous êtes limité aux 256 caractères que vous pouvez coder en Latin1.

4 votes

Bien sûr, dans JSON, vous pouvez toujours représenter les caractères non latins1 en utilisant des séquences d'échappement telles que \u20AC .

34 votes

Selon la norme JSON, vous n'êtes pas autorisé à utiliser le code latin1 pour l'encodage du contenu. Le contenu JSON doit être codé en unicode, que ce soit UTF-8, UTF-16 ou UTF-32 (big ou little endian).

24 votes

Il n'y a pas de paramètre charset sur application/json.

154voto

Drew Noakes Points 69288

Pour justifier l'affirmation de @deceze selon laquelle le codage JSON par défaut est UTF-8...

De IETF RFC4627 :

Le texte JSON DOIT être codé en Unicode. L'encodage par défaut est UTF-8.

Puisque les deux premiers caractères d'un texte JSON seront toujours ASCII ASCII [RFC0020], il est possible de déterminer si un flux d'octet d'octets est UTF-8, UTF-16 (BE ou LE), ou UTF-32 (BE ou LE) en regardant en regardant le motif des zéros dans les quatre premiers octets.

      00 00 00 xx  UTF-32BE
      00 xx 00 xx  UTF-16BE
      xx 00 00 00  UTF-32LE
      xx 00 xx 00  UTF-16LE
      xx xx xx xx  UTF-8

16 votes

Il est toujours utile de considérer JSON comme un format binaire, et non comme un format texte.

3 votes

Maintenant que la RFC4627 a été remplacée par la RFC7159, qui stipule que la valeur Root peut être une chaîne de caractères (en contraste explicite avec l'ancienne spécification), comment cela est-il mis en œuvre ? La spécification est vague à cet égard, et dit simplement que trois encodages sont autorisés, mais pas comment on est censé les différencier.

5 votes

@FabioBeltramini Ce qui précède devrait toujours être valable, car une chaîne de caractères en JSON ne contiendra pas de caractères nuls littéraux (les caractères nuls en JSON devraient être codés avec une séquence d'échappement numérique, à savoir "\u0000" ).

21voto

Alex Points 211

Notez que IETF RFC4627 a été remplacée par IETF RFC7158 . Dans la section [8.1], il rétracte le texte cité par @Drew plus tôt en disant :

Implementations MUST NOT add a byte order mark to the beginning of a JSON text.

0 votes

L'hypothèse reste cependant valable, car tout json valide commencera toujours par deux caractères ascii.

2 votes

Un caractère, car un seul chiffre est un fichier JSON valide.

0voto

Je suis exactement d'accord avec @deceze mais je veux développer ceci "Je reçois une erreur du service" partie de la question,

Nous obtenons ce genre d'erreurs comme http 415

Http 415 Unsupported Media type error (erreur de type de média non pris en charge)

Le code de réponse d'erreur client HTTP 415 Unsupported Media Type indique que le serveur refuse d'accepter la demande car le format des données utiles est dans un format non pris en charge.

Le problème de format peut être dû à l'indication de la demande. Content-Type ou Content-Encoding ou à la suite d'une inspection directe des données.

En d'autres termes, tel qu'il est vu dans cet exemple .

  • Nous devons définir le bon type de contenu et nous devons accepter le bon type de contenu. comme on le voit dans Add Content-Type: application/json y Accept: application/json . Sinon, il prendra la valeur par défaut

0voto

roipeker Points 883

L'implémentation de Dart http traite les octets grâce à ce "charset=utf-8", donc je suis sûr que plusieurs implémentations supportent cela, pour éviter le charset de repli "latin-1" lors de la lecture des octets de la réponse. Dans mon cas, je perds totalement le format du corps de la réponse, je dois donc encoder manuellement les octets en utf8, ou ajouter le paramètre "inner" de l'en-tête dans la réponse API de mon serveur.

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