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, j'obtiens une erreur du service. Je peux également utiliser avec succès Content-type: application/json
sans la partie ;charset=utf-8
.
Que fait exactement charset=utf-8
? Je sais que cela spécifie le codage de caractères mais le service fonctionne bien sans cela. Ce codage limite-t-il les caractères pouvant figurer dans le corps du message?
L’en-tête indique simplement en quoi le contenu est codé. Il n’est pas nécessairement possible de déduire le type du contenu du contenu lui-même, c’est-à-dire que vous ne pouvez pas simplement regarder le contenu et savoir quoi en faire. C’est à cela que servent les en-têtes HTTP: ils indiquent au destinataire le type de contenu avec lequel ils sont (supposément) traités.
Content-type: application/json; charset=utf-8
désigne le contenu au format JSON, codé au codage de caractères UTF-8. La désignation de l'encodage est quelque peu redondante pour JSON, car l'encodage par défaut (uniquement?) Pour JSON est UTF-8. Donc, dans ce cas, le serveur de destination est apparemment content de savoir qu'il traite avec JSON et suppose que l'encodage est UTF-8 par défaut, c'est pourquoi il fonctionne avec ou sans l'en-tête.
Ce codage limite-t-il les caractères pouvant figurer dans le corps du message?
Non, vous pouvez envoyer tout 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é UTF-8 mais que vous envoyez réellement du contenu codé en Latin1, le destinataire peut produire des données erronées, en essayant d'interpréter les données codées en Latin1 au format UTF-8. Si, bien sûr, vous indiquez 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 encoder en Latin1.
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. Le codage par défaut est UTF-8.
Puisque les deux premiers caractères d’un texte JSON seront toujours ASCII caractères [RFC0020], il est possible de déterminer si un flux d’octets est UTF-8, UTF-16 (BE ou LE) ou UTF. 32 (BE ou LE) en examinant le modèle de valeurs nulles 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
Notez que IETF RFC4627 a été remplacé par IETF RFC7158 . Dans la section [8.1], le texte cité précédemment par @Drew est retiré:
Implementations MUST NOT add a byte order mark to the beginning of a JSON text.
Dart http implémente le processus de mise en œuvre des octets grâce à ce "charset = utf-8", donc je suis sûr que plusieurs implémentations le supportent, pour éviter le jeu de caractères "latin-1" lors de la lecture des octets de la réponse. Dans mon cas, je perds totalement le format de la chaîne du corps de la réponse. Je dois donc coder les octets manuellement en utf8 ou ajouter le paramètre "inner" de cet en-tête à la réponse de l'API de mon serveur.
Je suis exactement d'accord avec @deceze mais je veux développer cette partie "Je reçois une erreur du service" ,
Nous obtenons ce genre d'erreurs comme http 415
Http 415 Erreur de type de support non supporté
Le code de réponse d'erreur client du type de support HTTP 415 non pris en charge indique que le serveur refuse d'accepter la demande, car le format de la charge utile est dans un format non pris en charge.
Le problème de format peut être dû à la demande Content-Type ou Content-Encoding , ou à l'inspection des données. directement.
En d'autres termes, comme dans https://stackoverflow.com/a/22643964/914284 cet exemple.