数据类型与编码
列举一下在 HTTP 里经常遇到的几个类别(也即 MIME type
):
-
text:即文本格式的可读数据,我们最熟悉的应该就是
text/html
了,表示超文本文档,此外还有纯文本text/plain
、样式表text/css
等。 -
image:即图像文件,有 image/gif、image/jpeg、image/png 等。
-
audio/video:音频和视频数据,例如 audio/mpeg、video/mp4 等。
-
application:数据格式不固定,可能是文本也可能是二进制,必须由上层应用程序来解释。
常见的有
application/json
,application/javascript
、application/pdf
等,另外,如果实在是不知道数据是什么类型,就会是application/octet-stream
,即不透明的二进制数据。
HTTP 在传输时为了节约带宽,有时候还会压缩数据,有一个 Encoding type
,告诉数据是用的什么编码格式,这样对方才能正确解压缩,还原出原始的数据。
常用的只有下面三种:
-
gzip:GNU zip 压缩格式,也是互联网上最流行的压缩格式;
-
deflate:zlib(deflate)压缩格式,流行程度仅次于 gzip;
-
br:一种专门为 HTTP 优化的新压缩算法(Brotli)。
有了 MIME type
和 Encoding type
,无论是浏览器还是服务器就都可以轻松识别出 body
的类型,也就能够正确处理数据了。
数据类型使用的头字段
HTTP 协议为此定义了 Accept 请求头字段
和 Content 实体头字段
,用于客户端和服务器进行“内容协商”。也就是说,客户端用 Accept 头
告诉服务器希望接收什么样的数据,而服务器用 Content 头
告诉客户端实际发送了什么样的数据。
Accept 字段标记的是客户端可理解的 MIME type,用 “,” 做分隔符列出多个类型,让服务器有更多的选择余地
// 这就是告诉服务器,请给我这四类格式的数据”。
Accept: text/html,application/xml,image/webp,image/png
相应的,服务器会在响应报文里用 头字段 Content-Type
告诉实体数据的真实类型:
Content-Type: text/html
Content-Type: image/png
Accept-Encoding
字段标记的是客户端支持的压缩格式,例如上面说的 gzip、deflate 等,同样也可以用“,”列出多个,服务器可以选择其中一种来压缩数据,实际使用的压缩格式放在响应头字段 Content-Encoding
里。如果请求报文里没有 Accept-Encoding
字段,就表示客户端不支持压缩数据;如果响应报文里没有 Content-Encoding
字段,就表示响应数据没有被压缩。
Accept-Encoding: gzip, deflate, br
Content-Encoding: gzip
语言类型与编码
不同国家不同地区的人使用了很多不同的语言,虽然都是 text/html,但如何让浏览器显示出每个人都可理解可阅读的语言文字呢?
这实际上就是“国际化”的问题。HTTP 又引入了两个概念:语言类型与字符集。举几个例子:en 表示任意的英语,en-US 表示美式英语,en-GB 表示英式英语,而 zh-CN 就表示我们最常使用的汉语。
Accept-Language
字段标记了客户端可理解的自然语言,也允许用“,”做分隔符列出多个类型,例如:
Accept-Language: zh-CN, zh, en
相应的,服务器应该在响应报文里用头字段 Content-Language
告诉客户端实体数据使用的实际语言类型:
Content-Language: zh-CN
同样的一段文字,用一种编码显示正常,换另一种编码后可能就会变得一团糟。
所以后来就出现了 Unicode 和 UTF-8,把世界上所有的语言都容纳在一种编码方案里,遵循 UTF-8 字符编码方式的 Unicode 字符集也成为了互联网上的标准字符集。
字符集在 HTTP 里使用的请求头字段是 Accept-Charset,但响应头里却没有对应的 Content-Charset,而是在 Content-Type 字段的数据类型后面用“charset=xxx”来表示,这点需要特别注意。
// 浏览器请求 GBK 或 UTF-8 的字符集
Accept-Charset: gbk, utf-8
// 服务器返回的是 UTF-8 编码
Content-Type: text/html; charset=utf-8
Tips:
-
content-type,实际上它是个通用字段,只要是有 body 就可以带,请求响应里都可以出现。
-
UTF-8 只是编码方案,Unicode是字符集。
网友评论