¿Qué significa “Content-type: application / json; charset = utf-8 “¿en serio?

Cuando realizo una solicitud POST con un cuerpo JSON para mi servicio REST, incluyo Content-type: application/json; charset=utf-8 Content-type: application/json; charset=utf-8 en el encabezado del mensaje. Sin este encabezado, recibo un error del servicio. También puedo usar Content-type: application/json sin la porción ;charset=utf-8 .

¿Qué hace exactamente charset=utf-8 ? Sé que especifica la encoding de caracteres pero el servicio funciona bien sin eso. ¿Esta encoding limita los caracteres que pueden estar en el cuerpo del mensaje?

El encabezado solo denota en qué está codificado el contenido. No es necesariamente posible deducir el tipo de contenido del contenido en sí mismo, es decir, no necesariamente se puede mirar el contenido y saber qué hacer con él. Para eso están los encabezados HTTP, le dicen al destinatario qué tipo de contenido (supuestamente) están tratando.

Content-type: application/json; charset=utf-8 Content-type: application/json; charset=utf-8 designa que el contenido está en formato JSON, codificado en la encoding de caracteres UTF-8. La designación de la encoding es algo redundante para JSON, ya que la encoding predeterminada (¿solo?) Para JSON es UTF-8. Entonces, en este caso, el servidor receptor aparentemente está contento de saber que se trata de JSON y asume que la encoding es UTF-8 de forma predeterminada, por eso funciona con o sin el encabezado.

¿Esta encoding limita los caracteres que pueden estar en el cuerpo del mensaje?

No. Puedes enviar lo que quieras en el encabezado y el cuerpo. Pero, si los dos no coinciden, puede obtener resultados incorrectos. Si especifica en el encabezado que el contenido está codificado en UTF-8 pero en realidad está enviando contenido codificado en Latin1, el receptor puede generar datos basura, tratando de interpretar datos codificados en Latin1 como UTF-8. Si, por supuesto, especifica que está enviando datos codificados en Latin1 y realmente lo está haciendo, entonces sí, está limitado a los 256 caracteres que puede codificar en Latin1.

Para corroborar la afirmación de @ deceze de que la encoding JSON predeterminada es UTF-8 …

De IETF RFC4627 :

El texto JSON DEBERÁ estar codificado en Unicode. La encoding predeterminada es UTF-8.

Como los dos primeros caracteres de un texto JSON siempre serán caracteres ASCII [RFC0020], es posible determinar si una secuencia de octetos es UTF-8, UTF-16 (BE o LE) o UTF-32 (BE o LE) observando el patrón de nulos en los primeros cuatro octetos.

  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 

Tenga en cuenta que IETF RFC4627 ha sido reemplazado por IETF RFC7158 . En la sección [8.1] retracta el texto citado por @Drew antes diciendo:

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