什么“内容类型:application / json; charset = utf-8”真的意味着什么?

时间:2012-02-13 02:37:19

标签: character-encoding mime-types

当我使用JSON正文向我的REST服务发出POST请求时,我在邮件头中包含Content-type: application/json; charset=utf-8。没有这个标题,我从服务中得到一个错误。我也可以在没有Content-type: application/json部分的情况下成功使用;charset=utf-8

charset=utf-8究竟做了什么?我知道它指定了字符编码,但没有它,服务工作正常。此编码是否限制了邮件正文中的字符?

6 个答案:

答案 0 :(得分:243)

标题仅表示内容的编码内容。不一定可以从内容本身推断内容的类型,即您不一定只看内容并知道如何处理它。这就是HTTP标头的用途,它们告诉收件人他们(应该)处理的是什么类型的内容。

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

  

此编码是否限制了邮件正文中的字符?

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

答案 1 :(得分:133)

证实@deceze声称默认的JSON编码是UTF-8 ......

来自IETF RFC4627

  

JSON文本应以Unicode编码。默认编码是     UTF-8。

     

由于JSON文本的前两个字符始终为ASCII     字符[RFC0020],可以确定是否为八位字节     通过查看,流是UTF-8,UTF-16(BE或LE)或UTF-32(BE或LE)     在前四个八位字节中的空值模式。

      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

答案 2 :(得分:18)

请注意,IETF RFC4627已被IETF RFC7158取代。在[8.1]节中,它通过以下方式撤回了@Drew引用的文字:

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

答案 3 :(得分:1)

我完全同意@deceze,但我想开发此问题的“我从服务中获取错误”

我们收到 http 415

这样的错误
  

Http 415不支持的媒体类型错误

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

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

换句话说,如本示例中的https://stackoverflow.com/a/22643964/914284中所示。

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

答案 4 :(得分:0)

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

答案 5 :(得分:0)

我使用HttpClient并返回了内容类型为@Override public int getItemCount() { return orderModels.size(); } 的响应标头,因为HttpClient默认为 ISO-8859-1 ,所以我丢失了诸如使用unicode的外语或符号之类的字符强>。因此,如@WesternGun所述,尽可能明确,以免出现任何可能的问题。

由于服务器无法为我处理请求的标题字符集(login_url = 'https://www.spotrac.com/signin/' data = { 'email': 'a****@gmail.com', 'password': '******' } with requests.Session() as s: response = requests.post(login_url , data) index_page= s.get('https://www.spotrac.com/nba/contracts/breakdown/2010/') soup = BeautifulSoup(index_page.text, 'html.parser') ),因此无法处理,我不得不将响应数据作为绘制字节进行检索,并使用UTF-8将其转换为String。因此,建议保持明确,并避免采用默认值。