🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
[TOC] ![](https://img.kancloud.cn/15/dd/15dd636ea7ec5a65f19590f83ffc1e99_1000x660.png) ## 二进制分帧 **最重要的改变,下面的优势都是根据这个衍生出来** HTTP 1.x的解析是基于文本。基于文本洗衣的格式解析存在天然缺陷,文本的表现形式有多样性,要做到健壮性考虑的场景必然很多,二进制则不同,只认0和1的组合,基于这种考虑HTTP2.0的协议解析决定采用二进制分帧格式,实现方便且健壮。 ![](https://img.kancloud.cn/43/cd/43cd44496ccc952e199a513e6a15bbc0_580x301.png) 所以HTTP/2引入了三个新的概念 > 1、数据流:基于TCP连接之上的逻辑双向字节流,对应一个请求及响应。客户端每发起一个请求就建立一个数据量就,后续该请求及其响应的所有数据都通过该数据流传输。 > 2、消息:一个请求或者响应对应的一系列数据帧 > 3、帧”:HTTP/2的最小数据切片单位,每个帧包含帧首部,至少也会标示出当前帧所属的流。 上述概念之间的逻辑关系: > 1、所有通信都在一个TCP连接上完成,此连接可以承载任意数量的双向数据流。 > 2、每个数据流都有一个唯一的标识符和可选的优先级信息,用于承载双向消息。 > 3、每条消息都是一条逻辑HTTP消息(例如请求或者响应),包含一个或多个帧。 > 4、帧是最小的通信单位,承载着特定类型的数据,例如HTTP标头、消息负载等等。来自不同数据流的帧可以交错发送,然后再根据每个帧头的数据流标识符重新组装。 > 5、每个HTTP消息分分解为多个独立的帧后可以交错发送,从而在宏观上实现了多个请求或者响应并行传输的效果。这类似于多进程环境下的时间分片机制。 所有HTTP 2.0通信都在一个连接上完成,这个连接可以承载任意数量的双向数据流。每个数据流以消息的形式发送。而消息由一或多个帧组成,而这些帧可以乱序发送,然后再根据每个帧首部流标识符重新组装。 ## 首部压缩 **第一次需要传完整的请求头部,后面只要穿与第一次不一样的头部消息就ok** 对于相同的数据,不再重新通过每次请求和响应发送。每个新的首部键值对要么追加到当前表的末尾,要么替换表中之前的值。**首部表在HTTP2.0的链接存续期内始终存在**,由客户端和服务端共同渐进的更新。 ![](https://img.kancloud.cn/07/01/07013ad53b857740c051dc6f10971047_774x639.png) ## 多路复用 **多个http可以在一个tcp连接中同时进行** 1. 可以并行交错的发送请求和响应,这些请求和响应之间互不影响 2. 只使用一个链接即可并行发送多个请求和响应 3. 消除不必要的延迟,从而减少页面加载的时间 4. 不必再为绕过HTTP1.x限制而多做很多工作 ## 请求优先级 //**可以控制优先响应哪些请求,比如一个网页,网页布局是最重要的,而图片资源不太重要,可以优先就诊网页布局** 把HTTP消息分为很多独立帧之后,就可以通过优化这些帧的交错和传输顺序进一步优化性能。 ### 什么是请求优先级 每个流都可以带有一个31bit的优先值:0表示最高优先级;2的31次方-1表示最低优先级。 ### 请求优先级如何工作 客户端明确指定优先级,服务端可以根据这个优先级作为交互数据的依据,比如客户端优先设置为.css>.js>.jpg。服务端按此顺序返回结果更加有利于高效利用底层连接,提高用户体验。然而,在使用请求优先级时应注意服务端是否支持请求优先级,是否会引起队首阻塞问题,比如高优先级的慢响应请求会阻塞其他资源的交互。 ## 服务器推送 HTTP2.0新增的一个强大的新功能,就是服务器可以对一个客户端请求发送多个响应。服务器向客户端推送资源无需客户端明确的请求。 ### 什么是服务器推送(HTTP2.0中) 服务端根据客户端的请求,提前返回多个响应,推送额外的资源给客户端。如下图,客户端请求stream 1(/page.html)。服务端在返回stream 1的消息的同时推送了stream 2(/script.js)和stream 4(/style.css) ![](https://img.kancloud.cn/14/ef/14ef99a95afff120d4e48ddcbd79071e_492x211.png) ### 服务器推送如何工作 * PUSH\_PROMISE帧是服务端向客户端有意推送资源的信号。 * PUSH\_PROMISE帧中只包含预推送资源的首部。如果客户端对PUSH\_PROMISE帧没有意见,服务端在PUSH\_PROMISE帧后发送响应的DATA帧。如果客户端已经缓存了该资源,不需要推送,可以拒绝PUSH\_PROMISE帧。 * PUSH-PROMISE必须遵循请求-响应原则,**只能借着对请求的响应推送资源**。 * **PUSH\_PROMISE帧必须在返回响应之前发送,**以免客户端出现竞态条件(竞态条件是指在多线程的情况下不同的执行顺序会导致计算机执行出不同的结果正确性不同) * HTTP2.0连接后,客户端与服务端交换SETTINGS帧,借此限定双向并发的最大数量。因此,客户端可以限定推送流的数量,或者通过把这个只设置为0来完全禁止服务器推送。 * 所有推送的资源都必须遵守同源策略。换句话说,服务器不能随便将第三方资源推送给客户端,而必须是经过双方的确认才行。 ### 服务器推送对性能优化工作的贡献 服务端推送是一种在客户端请求之前发送数据的机制。在HTTP2.0中,服务器可以对一个客户端的请求发送多个响应。如果一个请求是由你的主页发送的,服务器可能会响应主页内容、logo以及样式表,因为他知道客户端会用到这些东西。这样不但减轻了数据传送冗余步骤,也加快了页面响应的速度,提高了用户体验。 ## 参考资料 [http2.0](https://www.jianshu.com/p/1ad439279974) [HTTP----HTTP2.0新特性](https://juejin.im/post/5a4dfb2ef265da43305ee2d0)