影响一个HTTP网络请求的因素主要有两个:带宽和延迟。css
1996年5月,HTTP/1.0 版本发布,内容大大增长。html
首先,任何格式的内容均可以发送。这使得互联网不只能够传输文字,还能传输图像、视频、二进制文件。这为互联网的大发展奠基了基础。git
其次,除了GET命令,还引入了POST命令和HEAD命令,丰富了浏览器与服务器的互动手段。github
再次,HTTP请求和回应的格式也变了。除了数据部分,每次通讯都必须包括头信息(HTTP header),用来描述一些元数据。算法
其余的新增功能还包括状态码(status code)、多字符集支持、多部分发送(multi-part type)、权限(authorization)、缓存(cache)、内容编码(content encoding)等。浏览器
HTTP/1.0 版的主要缺点是,每一个TCP链接只能发送一个请求。发送数据完毕,链接就关闭,若是还要请求其余资源,就必须再新建一个链接。缓存
TCP链接的新建成本很高,由于须要客户端和服务器三次握手,而且开始时发送速率较慢(slow start)。因此,HTTP 1.0版本的性能比较差。随着网页加载的外部资源愈来愈多,这个问题就愈发突出了。安全
1997年1月,HTTP/1.1 版本发布,只比 1.0 版本晚了半年。它进一步完善了 HTTP 协议,一直用到了20年后的今天,直到如今仍是最流行的版本。服务器
1.1 版的最大变化,就是引入了持久链接(persistent connection),即TCP链接默认不关闭,能够被多个请求复用,不用声明Connection: keep-alive。网络
客户端和服务器发现对方一段时间没有活动,就能够主动关闭链接。不过,规范的作法是,客户端在最后一个请求时,发送Connection: close,明确要求服务器关闭TCP链接。
Connection: close
目前,对于同一个域名,大多数浏览器容许同时创建6个持久链接。
1.1 版还引入了管道机制(pipelining),即在同一个TCP链接里面,客户端能够同时发送多个请求。这样就进一步改进了HTTP协议的效率。
举例来讲,客户端须要请求两个资源。之前的作法是,在同一个TCP链接里面,先发送A请求,而后等待服务器作出回应,收到后再发出B请求。管道机制则是容许浏览器同时发出A请求和B请求,可是服务器仍是按照顺序,先回应A请求,完成后再回应B请求。
一个TCP链接如今能够传送多个回应,势必就要有一种机制,区分数据包是属于哪个回应的。这就是Content-length字段的做用,声明本次回应的数据长度。
Content-Length: 3495
上面代码告诉浏览器,本次回应的长度是3495个字节,后面的字节就属于下一个回应了。
在1.0版中,Content-Length字段不是必需的,由于浏览器发现服务器关闭了TCP链接,就代表收到的数据包已经全了。
使用Content-Length字段的前提条件是,服务器发送回应以前,必须知道回应的数据长度。
对于一些很耗时的动态操做来讲,这意味着,服务器要等到全部操做完成,才能发送数据,显然这样的效率不高。更好的处理方法是,产生一块数据,就发送一块,采用"流模式"(stream)取代"缓存模式"(buffer)。
所以,1.1版规定能够不使用Content-Length字段,而使用"分块传输编码"(chunked transfer encoding)。只要请求或回应的头信息有Transfer-Encoding字段,就代表回应将由数量未定的数据块组成。
Transfer-Encoding: chunked
每一个非空的数据块以前,会有一个16进制的数值,表示这个块的长度。最后是一个大小为0的块,就表示本次回应的数据发送完了。下面是一个例子。
HTTP/1.1 200 OK Content-Type: text/plain Transfer-Encoding: chunked 25 This is the data in the first chunk 1C and this is the second one 3 con 8 sequence 0
1.1版还新增了许多动词方法:PUT、PATCH、HEAD、 OPTIONS、DELETE。
另外,客户端请求的头信息新增了Host字段,用来指定服务器的域名。
Host: www.example.com
有了Host字段,就能够将请求发往同一台服务器上的不一样网站,为虚拟主机的兴起打下了基础。
虽然1.1版容许复用TCP链接,可是同一个TCP链接里面,全部的数据通讯是按次序进行的。服务器只有处理完一个回应,才会进行下一个回应。要是前面的回应特别慢,后面就会有许多请求排队等着。这称为"队头堵塞"(Head-of-line blocking)。
为了不这个问题,只有两种方法:一是减小请求数,二是同时多开持久链接。这致使了不少的网页优化技巧,好比合并脚本和样式表、将图片嵌入CSS代码、域名分片(domain sharding)等等。若是HTTP协议设计得更好一些,这些额外的工做是能够避免的。
HTTP1.0最先在网页中使用是在1996年,那个时候只是使用一些较为简单的网页上和网络请求上,而HTTP1.1则在1999年才开始普遍应用于如今的各大浏览器网络请求中,同时HTTP1.1也是当前使用最为普遍的HTTP协议。 主要区别主要体如今:
区别用一张图来体现:
2009年,谷歌公开了自行研发的 SPDY 协议,主要解决 HTTP/1.1 效率不高的问题。
这个协议在Chrome浏览器上证实可行之后,就被看成 HTTP/2 的基础,主要特性都在 HTTP/2 之中获得继承。
2012年google如一声惊雷提出了SPDY的方案,优化了HTTP1.X的请求延迟,解决了HTTP1.X的安全性,具体以下:
SPDY位于HTTP之下,TCP和SSL之上,这样能够轻松兼容老版本的HTTP协议(将HTTP1.x的内容封装成一种新的frame格式),同时可使用已有的SSL功能。
HTTP2.0:SPDY的升级版
HTTP2.0能够说是SPDY的升级版(其实本来也是基于SPDY设计的),可是,HTTP2.0 跟 SPDY 仍有不一样的地方,以下:
HTTP2.0和SPDY的区别:
这是 Akamai 公司创建的一个官方的演示,用以说明 HTTP/2 相比于以前的 HTTP/1.1 在性能上的大幅度提高。 同时请求 379 张图片,从Load time 的对比能够看出 HTTP/2 在速度上的优点。
https://http2.akamai.com/demo
在应用层与传输层之间增长一个二进制分帧层,以此达到“在不改动 HTTP 的语义,HTTP 方法、状态码、URI 及首部字段的状况下,突破 HTTP1.1 的性能限制,改进传输性能,实现低延迟和高吞吐量。”
在二进制分帧层上,HTTP2.0 会将全部传输的信息分割为更小的消息和帧,并对它们采用二进制格式的编码,其中 HTTP1.x 的首部信息会被封装到 Headers 帧,而咱们的 request body 则封装到 Data 帧里面。
插播一些基础概念:
对于 HTTP1.1,浏览器一般最多有连接的限制,即便开启多个连接,也须要付出不小的代价。而多路复用容许同时经过单一的 HTTP2.0 链接发起多重的“请求-响应”消息。
客户端和服务器能够把 HTTP 消息分解为互不依赖的帧,而后乱序发送,最后再在另外一端把它们从新组合起来。注意,同一连接上有多个不一样方向的数据流在传输。客户端能够一边乱序发送 stream,也能够一边接收者服务器的响应,而服务器那端同理。
也就是说, HTTP2.0 通讯都在一个链接上完成,这个链接能够承载任意数量的双向数据流。就比如,我请求一个页面 http://www.qq.com 。页面上全部的资源请求都是客户端与服务器上的一条 TCP 上请求和响应的!
能够请求的时候告知服务器端,资源分配权重,优先加载重要资源;
既然全部资源都是并行交错发送,会不会出现这样的状况 浏览器明明在等关键的 CSS 和 JS,你 TMD 的服务器还在发送图片?
每一个 HTTP2.0 流里面有个优先值,这个优先值肯定着客户端和服务器处理不一样的流采起不一样的优先级策略,高优先级的流都应该优先发送,但又不会绝对的。绝对地准守,可能又会引入首队阻塞的问题:高优先级的请求慢致使阻塞其余资源交付。分配处理资源和客户端与服务器间的带宽,不一样优先级的混合也是必须的。
因此就不会出现如上描述的这种状况了。
由于 HTTP/2 的数据包是不按顺序发送的,同一个链接里面连续的数据包,可能属于不一样的回应。所以,必需要对数据包作标记,指出它属于哪一个回应。
HTTP/2 将每一个请求或回应的全部数据包,称为一个数据流(stream)。每一个数据流都有一个独一无二的编号。数据包发送的时候,都必须标记数据流ID,用来区分它属于哪一个数据流。另外还规定,客户端发出的数据流,ID一概为奇数,服务器发出的,ID为偶数。
数据流发送到一半的时候,客户端和服务器均可以发送信号(RST_STREAM帧),取消这个数据流。1.1版取消数据流的惟一方法,就是关闭TCP链接。这就是说,HTTP/2 能够取消某一次请求,同时保证TCP链接还打开着,能够被其余请求使用。
客户端还能够指定数据流的优先级。优先级越高,服务器就会越早回应。
HTTP 协议不带有状态,每次请求都必须附上全部信息。因此,请求的不少字段都是重复的,好比Cookie和User Agent,如出一辙的内容,每次请求都必须附带,这会浪费不少带宽,也影响速度。
HTTP/2 对这一点作了优化,引入了头信息压缩机制(header compression)。一方面,头信息使用gzip或compress压缩后再发送;另外一方面,客户端和服务器同时维护一张头信息表,全部字段都会存入这个表,生成一个索引号,之后就不发送一样字段了,只发送索引号,这样就提升速度了。
HTTP/2 容许服务器未经请求,主动向客户端发送资源,这叫作服务器推送(server push)。
常见场景是客户端请求一个网页,这个网页里面包含不少静态资源。正常状况下,客户端必须收到网页后,解析HTML源码,发现有静态资源,再发出静态资源请求。其实,服务器能够预期到客户端请求网页后,极可能会再请求静态资源,因此就主动把这些静态资源随着网页一块儿发给客户端了。
参考:
https://github.com/eteplus/blog/issues/3
https://www.jianshu.com/p/be29d679cbff
http://www.alloyteam.com/2016/07/httphttp2-0spdyhttps-reading-this-is-enough/#prettyPhoto
http://www.alloyteam.com/2015/03/http2-0-di-qi-miao-ri-chang/#prettyPhoto
https://liyaoli.com/2015-04-18/HTTP-2.0.html
http://www.ruanyifeng.com/blog/2016/08/http.html