关于字符编码:“内容类型:application / json; charset = utf-8”真的是什么意思?

What does “Content-type: application/json; charset=utf-8” really mean?

当我向REST服务发出带有JSON正文的POST请求时,我在消息标头中包含Content-type: application/json; charset=utf-8。 没有此标头,我会从服务中获取错误。 我也可以成功使用Content-type: application/json而无需;charset=utf-8部分。

charset=utf-8到底是做什么的? 我知道它指定了字符编码,但是如果没有它,服务就可以正常工作。 这种编码是否限制了邮件正文中可以包含的字符?


标头仅表示内容被编码的内容。不一定可以从内容本身推断出内容的类型,即,您不必仅查看内容并知道如何处理。这就是HTTP标头的用途,它们告诉接收者(据说)正在处理哪种内容。

Content-type: application/json; charset=utf-8将内容指定为JSON格式,并以UTF-8字符编码进行编码。指定编码对于JSON有点多余,因为JSON的默认(仅?)编码为UTF-8。因此,在这种情况下,接收服务器显然很高兴知道它正在处理JSON,并假定默认情况下编码为UTF-8,因此它可以与标头一起使用,也可以不与标头一起使用。

Does this encoding limit the characters that can be in the message body?

否。您可以在标题和正文中发送您想要的任何内容。但是,如果两者不匹配,您可能会得到错误的结果。如果您在标头中指定内容是UTF-8编码的,但实际上是在发送Latin1编码的内容,则接收方可能会产生垃圾数据,试图将Latin1编码的数据解释为UTF-8。当然,如果您指定要发送的是Latin1编码的数据,而实际上是在发送,那么可以,您只能使用Latin1编码的256个字符。


为了证实@deceze的说法,即默认JSON编码为UTF-8 ...

从IETF RFC4627:

JSON text SHALL be encoded in Unicode. The default encoding is
UTF-8.

Since the first two characters of a JSON text will always be ASCII
characters [RFC0020], it is possible to determine whether an octet
stream is UTF-8, UTF-16 (BE or LE), or UTF-32 (BE or LE) by looking
at the pattern of nulls in the first four octets.

1
2
3
4
5
      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


请注意,IETF RFC4158已被IETF RFC7158取代。在第[8.1]节中,它撤回了@Drew先前引用的文本,说:

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


Dart http的实现通过" charset = utf-8"来处理字节,因此我确定那里有几种实现都支持此功能,以避免从响应中读取字节时避免使用" latin-1"后备字符集。
就我而言,我完全丢失了响应主体字符串的格式,因此我必须手动对utf8进行字节编码,或者在服务器的API响应中添加该标头" inner"参数。


我完全同意@deceze,但我想提出问题的"服务中出现错误"部分,

我们收到的这类错误为http 415

Http 415 Unsupported Media type error

HTTP 415不受支持的媒体类型客户端错误响应代码指示服务器拒绝接受请求,因为有效负载格式为不受支持的格式。

格式问题可能是由于请求指示的Content-Type或Content-Encoding,或者是直接检查数据的结果。

换句话说,例如在https://stackoverflow.com/a/22643964/914284中看到的此示例。

  • 我们必须设置正确的内容类型,我们必须接受正确的内容类型
    如添加内容类型:application / json和接受:application / json。否则将采用默认值