目录:
css
参考的文章:html
HTTP1.1默认使用长链接,可有效减小TCP的三次握手开销。
HTTP 1.0规定浏览器与服务器只保持短暂的链接,浏览器的每次请求都须要与服务器创建一个TCP链接,服务器完成请求处理后当即断开TCP链接
当一个网页文件中包含了不少图像的地址的时候,那就须要不少次的http请求和响应,每次请求和响应都须要一个单独的链接,每次链接只是传输一个文档和图像,上一次和下一次请求彻底分离。即便图像文件都很小,可是客户端和服务器端每次创建和关闭链接倒是一个相对比较费时的过程,而且会严重影响客户机和服务器的性能。当一个网页文件中包含JavaScript文件,CSS文件等内容时,也会出现相似上述的状况。
为了克服HTTP 1.0的这个缺陷,HTTP 1.1支持持久链接(HTTP/1.1的默认模式使用带流水线的持久链接),在一个TCP链接上能够传送多个HTTP请求和响应,减小了创建和关闭链接的消耗和延迟。一个包含有许多图像的网页文件的多个请求和应答能够在一个链接中传输,但每一个单独的网页文件的请求和应答仍然须要使用各自的链接。node
HTTP 1.1还容许客户端不用等待上一次请求结果返回,就能够发出下一次请求,但服务器端必须按照接收到客户端请求的前后顺序依次回送响应结果,以保证客户端可以区分出每次请求的响应内容,这样也显著地减小了整个下载过程所须要的时间。算法
经过请求头中connection字段在代表是否支持长连接
在http1.1中,client和server都是默认对方支持长连接的(即connection的值默认我Keep-Alive), 若是client使用http1.1协议,但又不但愿使用长连接,则须要在header中指明connection的值为closer(connection默认为Keep-Alive);若是server方也不想支持长连接,则在response中也须要明确说明connection的值为closer。不论request仍是response的header中包含了值为closer的connection,都代表当前正在使用的tcp连接在当天请求处理完毕后会被断掉。之后client再进行新的请求时就必须建立新的tcp连接了。浏览器
若是服务器认为客户端有权限请求服务器,则返回100,不然返回401。客户端若是接受到100,才开始把请求body发送到服务器。这样当服务器返回401的时候,客户端就能够不用发送请求body了,节约了带宽。另外HTTP还支持传送内容的一部分。这样当客户端已经有一部分的资源后,只须要跟服务器请求另外的部分资源便可。这是支持文件断点续传的基础。缓存
RANGE:bytes是HTTP/1.1新增内容,HTTP/1.0每次传送文件都是从文件头开始,即0字节处开始。RANGE:bytes=XXXX表示要求服务器从文件XXXX字节处开始传送,这就是咱们平时所说的断点续传!服务器
HTTP1.0是没有host域的,HTTP1.1才支持这个参数。
1.0中WEB浏览器没法使用主机头名来明确表示要访问服务器上的哪一个WEB站点,这样就没法使用WEB服务器在同一个IP地址和端口号上配置多个虚拟WEB站点。在HTTP 1.1中增长Host请求头字段后,WEB浏览器可使用主机头名来明确表示要访问服务器上的哪一个WEB站点,这才实现了在一台WEB服务器上能够在同一个IP地址和端口号上使用不一样的主机名来建立多个虚拟WEB站点。cookie
HTTP 1.1还提供了与身份认证、状态管理和Cache缓存等机制相关的请求头和响应头。tcp
多路复用容许同时经过单一的 HTTP/2 链接发起多重的请求-响应消息。
"HTTP1.1在同一时间对于同一个域名的请求数量有限制,超过限制就会阻塞请求"。多路复用底层采用增长二进制分帧层的方法,使得不改变原来的语义、首部字段的状况下提升传输性能,下降延迟。
二进制分帧将全部传输信息分割为更小的帧,用二进制进行编码,多个请求都在同一个TCP链接上完成,能够承载任意数量的双向数据流。HTTP/2更有效的使用TCP链接,获得性能上的提高。
性能
二进制分帧层把数据转换为二进制的同时,也把数据分红了一个一个的帧。帧是HTTP/2中数据传输的最小单位;每一个帧都有
stream_ID
字段,表示这个帧属于哪一个流,接收方把stream_ID
相同的全部帧组合到一块儿就是被传输的内容了。而流是HTTP/2中的一个逻辑上的概念,它表明着HTTP/1.1中的一个请求或者一个响应,协议规定client发给server的流的stream_ID
为奇数,server发给client的流ID是偶数。须要注意的是,流只是一个逻辑概念,便于理解和记忆的,实际并不存在。在一个TCP连接中,能够同时双向地发送帧,并且不一样流中的帧能够交错发送,不须要等某个流发送完,才发送下一个。也就是说在一个TCP链接中,能够同时传输多个流,便可以同时传输多个HTTP请求和响应,这种同时传输不须要遵循先入先出等规定,所以也不会产生阻塞,效率极高。
在 HTTP/1 中,HTTP 请求和响应都是由「状态行、请求 / 响应头部、消息主体」三部分组成。通常而言,消息主体都会通过 gzip 压缩,或者自己传输的就是压缩事后的二进制文件(例如图片、音频),但状态行和头部却没有通过任何压缩,直接以纯文本传输。
随着 Web 功能愈来愈复杂,每一个页面产生的请求数也愈来愈多,根据 HTTP Archive 的统计,当前平均每一个页面都会产生上百个请求。愈来愈多的请求致使消耗在头部的流量愈来愈多,尤为是每次都要传输 UserAgent、Cookie 这类不会频繁变更的内容,彻底是一种浪费。
Hapck原理:
具体规则能够描述为:
- 通讯双方共同维护了一份静态表,包含了常见的头部名称与值的组合
- 根据先入先出的原则,维护一份可动态添加内容的动态表
- 用基于该静态哈夫曼码表的哈夫曼编码数据
当要发送一个请求时,会先将其头部和静态表对照,对于彻底匹配的键值对,能够直接使用一个数字表示,如method: GET,对于头部名称匹配的键值对,能够将名称使用一个数字传输,同时告诉服务端将它添加到动态表中,之后的相同键值对就用一个数字表示了。这样,像cookie这些不常常变更的值,只用发送一次就行了。
即服务器发送/user.html
时,就能够主动把/user.js
和style.css
push给浏览器,使资源提早达到浏览器;除了静态文件,还能够推送比较耗时的API,只是须要提早将参数和cookie等信息经过某个方式告知服务端(如和路由关联)。Apache、GO的net/http、node-spdy都实现了server push(但ngnix没有=_=) Server push是HTTP/2协议里面惟一一个须要开发者本身配置的功能。其余功能都是服务器和浏览器自动实现,无需开发者介入。 在HTTP1.1时代,也有提早获取资源的方法,如preload和prefetch,前者是在页面解析初期就告诉浏览器,这个资源是浏览器立刻要用到的,能够马上发送对资源的请求,当须要用到该资源时就能够直接用而不用等待请求和响应的返回了;后者是当前页面用不到但下一页面可能会用到的资源,优先级较低,只有当浏览器空闲时才会请求prefetch标记的资源。从应用层面上看,preload和server push并无什么区别,可是server push减小浏览器请求的时间,略优于preload,在一些场景中,能够将二者结合使用。