简介
http协议属于应用层协议,我们知道,通过传输层协议已经可以让数据是从一个主机传送到任意一台主机,并且确定数据是从哪个应用发出,需要哪个应用接受。既然如此,为什么还需要一个应用层协议呢?这是因为,互联网是一个开放架构,数据格式五花八门,有文本、二进制、FDP等等,如果不规定数据的格式,通信双方是没法解析的。
所以,http协议的目的就是规定数据的格式,以便通信双方解析
HTTP/1.0
相比于最原始的0.9版本,HTTP/1.0定义了请求方式GET、POST、HEAD,规定请求和响应报文的格式,除了数据部分,还需要包括头信息(HTTP header),用来描述一些元数据
header包含的主要功能有:状态码(status code),多字符集,多部分传输(multipart type),内容编码(content encoding),内容格式(content type),权限(authorization),缓存(cache)
请求报文格式
GET /HTTP/1.0
accept:html/text;charset=utf-8
accept-encoding:zip
第一行是请求方式和支持的协议版本。后面是多行的header,用来描述客户端的信息
响应报文格式
HTTP/1.0 200 ok
content-type:text
content-encoding:zip
<html>
<body>Hello World</body>
</html>
格式是响应头+空行(\n\r)+数据,其中响应头的第一行是:支持的协议版本+状态码+描述信息
header
content-type
对于字符编码,HTTP/1.0规定头信息必须是ASCII编码,数据可以是任意格式,所以必须明确说明数据是什么格式,通信双方才能根据格式做不同的解析处理,content-type就是这个作用
内置了很多content-type值,格式为一级类型/二级类型,还可以在后面以;的形式追加参数
html/text;charset=utf-8)
该type表示,数据是网页格式,并且使用utf-8编码
客户端可以使用accept这个header说明自己接受哪些数据格式
content-encoding
因为数据是可以是各种格式,对于太大的数据就可能需要压缩传输,content-encoding就是用指定数据的压缩格式,客户端可以用accept-encoding说明可接受的压缩格式
content-range
用来说明数据的长度范围,格式为
xxx-xxx 从xxx到xxx
xxx- 从xxx开始到数据的最后
-xxx 从数据的开始到xxx
客户端可以使用range来指定要请求的数据范围,这就是断点续传的原理
缺点
HTTP/1.0的主要缺点是,每个TCP连接只能发送一个请求,请求结束后就断开连接,下次请求时就必须重新建立一个连接
但是建立TCP链接的成本是很高的,因为要三次握手,所以1.0版本的性能较差,当请求的资源越多问题就越发明显
HTTP/1.1
针对1.0性能的不足, HTTP/1.1版本做了大量改进,至今仍是最流行的版本
持久连接
http1.1引入了持久连接,即默认TCP连接不会关闭,可以被多个请求复用。当客户端或者服务端发现在某一段时间内没有请求后,其中一方主动断开连接。
管道机制
HTTP1.0时,在同一个TCP连接里面,多个请求是按照顺序发送的,即请求A返回后,才会发送请求B。1.1引入了管道机制,允许客户端同时发送请求A和B,这样就进一步提升了效率,但是服务端返回的时候仍然是先返回A响应再返回B响应
content-length
现在在同一个TCP连接中,服务端可以回传多个响应,就需要有一种机制来说明当前数据属于哪一个响应,content-length就表示本次响应的长度。后面的字节就属于下一个响应了
分段传输编码
利用content-length可以表示数据属于哪一个响应,缺点是服务器发回之前就必须知道数据的长度,即要等到一次响应完全结束才能返回数据,如果操作很耗时,那效率就很差。
分段传输编码解决是这个问题,数据产生一块,就传输一块。只要请求或者响应头中由transfer-encoding:chunk,就表示数据由数量未知的数据块组成,每一个数据块都有对应的16进制数,表示该数据块的长度,当数据块长度为0,表示本次数据发送完成
缺点
虽然1.1允许TCP复用,在一个TCP连接中也允许客户端同时发送多请求,但是服务器响应的时候需要按照顺序一个一个返回,如果某个响应过于耗时,即使后面的响应已经准备好,也得等待前面的响应完成才能回传,这就是对头堵塞
HTTP/2
http2在1.1的基础上,又做了大量性能上的改进,使效率和性能都有了巨大的提升
二进制协议
1.1规定头信息的ASCII编码,即文本格式,数据可以是文本也可以是二进制。HTTP2则完全是二进制协议,头信息和数据都是二进制格式,称为帧(frame):头信息帧和数据帧。
二进制协议的一个好处是,可以定义额外的帧。HTTP/2 定义了近十种帧,为将来的高级应用打好了基础。如果使用文本实现这种功能,解析数据将会变得非常麻烦,二进制解析则方便得多。
多工
HTTP2中,允许客户端或者服务端同时发送多个请求和响应,而且不必按照顺序发送,这样就解决了对头堵塞的问题
举个例子,客户端发送了请求A和B,服务端响应A一部分数据后发现很耗时,就响应B,然后再响应A的剩余数据
数据流
头信息压缩
HTTP规定每次请求都必须携带头信息,但是很多字段都是重复的,同样的header每次都的携带,浪费带宽也影响数据速度
HTTP2.0做了优化,第一:把头信息通过Gzip或者compress压缩,第二:客户端和服务端同时维护一张表,所以字段都在这张表内,生成索引号,发送的时候只发送索引号,这样就提高了速度