1

一、定义
http协议:超文本传输协议(通信协议),用于从服务器传输超文本到本地浏览,建立再TCP/IP协议基础上
三个特点:
1、无连接
是限制每次连接只处理一个请求。服务器处理完客户的请求,并收到客户的应答后,即断开连接。采用这种方式可以节省传输时间
2、无状态
是指协议对于事务处理没有记忆能力。缺少状态意味着如果后续处理需要前面的信息,则它必须重传,这样可能导致每次连接传送的数据量增大。另一方面,在服务器不需要先前信息时它的应答就较快
3、灵活
允许传输任意类型的数据对象。传输的类型由Content-Type(Content-Type是HTTP包中用来表示内容类型的标识)加以标记

image.png


HTTP/0.9版本
特点:结构简单,仅有GET请求,纯文本格式

例如GET /index.html
表示:TCP建立连接后,客户端向服务端请求index.html页面,协议规定,服务端只能返字符串,返回后即关闭TCP链接,如果请求的页面不存在,也不反悔任何错误码,这也是无状态的一个体现

HTTP/1.0版本
相比较上一个版本增加了如下主要内容:

  1. 增加了post请求,丰富了浏览器与客户端的互动手段
  2. 传输数据不限于文本,可以是图片、视频、二进制文件等内容
  3. 增加了协议版本号
  4. 增加的响应状态码
  5. 引入了HTTP HEADER(头部)概念,让HTTP处理请求更加灵活
GET /HTTP/1.0
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_5)
Accept: */*

HTTP/1.0 200 OK
Content-Type: text/plain
Content-Length: 137582
Expires: Thu, 05 Dec 1997 16:00:00 GMT
Last-Modified: Wed, 5 August 1996 15:55:28 GMT
Server: Apache 0.84

<html>
  <body>Hello World</body>
</html>

其中content-type是体现灵活的字段,我们常见的value值包括:text/html, text/css, image/png, application/javascript, application/x-www-form-urlencoded form, Multipart/form-data,以上数据统称为MIME类型。

1.0的缺点:
连接无法复用:每个TCP连接只能发送一个请求。发送数据完毕,连接就关闭,如果还要请求其他资源,就必须再新建一个连接。
为了解决这个问题,有些浏览器在请求时,用了一个非标准的Connection字段:Connection: keep-alive,表示TCP可以复用,直到主动关闭链接。

image.png

上面是又没有keep-alive的区别,但是这不是标准字段,不同实现的行为可能不一致,因此不是根本的解决办法,并且TCP的新建成本很高,因为每次链接服务端和客户端都需要经过三次握手,并且开始时发送的速率较慢。

HTTP/1.1版本
也就是目前位置用的最多的一个版本,相比较1.0版本增加了:

  1. 持久链接,默认TCP不关闭,可以被多个请求复用,不用申明connection:keep-alive字段
  2. 新增了PUT、PATCH、OPTIONS、DELETE请求方法,也新增了许多状态码
  3. 强制HOST头:HTTP1.0中认为每台服务器都绑定一个唯一的IP地址,因此,请求消息中的URL并没有传递主机名(hostname)。但随着虚拟主机技术的发展,在一台物理服务器上可以存在多个虚拟主机(Multi-homed Web Servers),并且它们共享一个IP地址。HTTP1.1的请求消息和响应消息都应支持Host头域,且请求消息中如果没有Host头域会报告一个错误(400 Bad Request)。有了Host字段,就可以将请求发往同一台服务器上的不同网站,为虚拟主机的兴起打下了基础
  4. 缓存处理:HTTP/1.0 使用 Pragma:no-cache + Last-Modified/If-Modified-Since + Expire来作为缓存判断的标准;HTTP/1.1 引入了更多的缓存控制策略:Cache-Control、Etag/If-None-Match
  5. 管道机制(pipelining):即在同一个TCP链接里面,客户端可以同事发送多个请求。从而进一步改善HTTP协议的效率问题

    例如:客户端需要请求两个资源。以前的做法是,在同一个TCP连接里面,先发送A请求,然后等待服务器做出回应,收到后再发出B请求。管道机制则是允许浏览器同时发出A请求和B请求,但是服务器还是按照顺序,先回应A请求,完成后再回应B请求,通过下图可以很清晰的看出区别
    image.png

1.1缺点:
虽然1.1版允许复用TCP连接,但是同一个TCP连接里面,所有的数据通信是按次序进行的。服务器只有处理完一个回应,才会进行下一个回应。要是前面的回应特别慢,后面就会有许多请求排队等着。这称为“队头堵塞"(Head-of-line blocking)
解决方案:
1、减少请求数量(雪碧图)
2、多开持久链接,如下图中并行的请求,就是多开了几个TCP链接,但是浏览器也有规定,同一域名下TCP开启的个数时有限,一般不超过10个,这也是SEO中,将资源CDN的原因。

image.png

个人见解:1.1版本中增加了许多头部的标识,使得请求更加的灵活,例如类型、缓存等等!利用好了能大幅提升请求效率,也可以当作优化的重点去攻克!但是也有太多的字段需要去学习,有利有弊吧!接下来就是重点HTTP/2

HTTP/2版本
为什么是2而不是2.0,因为标准委员会不准备发布子版本,下一个版本将是HTTP/3
1、二进制传输:在HTTP1.x中,我们是通过文本的方式传输数据。基于文本的方式传输数据存在很多缺陷,文本的表现形式有多样性,因此要做到健壮性考虑的场景必然有很多,但是二进制则不同,只有0和1的组合,因此选择了二进制传输,实现方便且健壮。为了保证HTTP不受影响,那就需要在应用层(HTTP2.0)和传输层(TCP or UDP)之间增加一个二进制分帧层。在二进制分帧层上,HTTP2.0会将所有传输的信息分为更小的消息和帧,并采用二进制格式编码,其中HTTP1.x的首部信息会被封装到Headers frame,而Request Body则封装到Data frame。
image.png

2、头部压缩(Header Compression):专门为头部压缩设计了Hpack算法,简单来说就是客户端和服务端共同维护一份相同的静态表和动态表,在编码时直接用表的index代替,可以大幅降低头部大小
image.png

3、服务端推送(server push):允许服务器未经请求,主要向客户端发送资源。

客户端请求一个网页,这个网页里面包含很多静态资源。正常情况下,客户端必须收到网页后,解析HTML源码,发现有静态资源,再发出静态资源请求。其实,服务器可以预期到客户端请求网页后,很可能会再请求静态资源,所以就主动把这些静态资源随着网页一起发给客户端了

4、多路复用:也是最重要的一项,起因是1.X版本中的“队头阻塞”,这里面有三个比较重要的概念

  • 消息:逻辑上的http消息,比如一系列Data frame 和 一个Header frame 组成的请求消息
  • 帧(frame):最小的数据单位
  • 流(stream):多个帧组成数据流,每个帧会标识出该帧属于哪个流,通俗讲流是连接中的一个虚拟信道,可以承载双向消息传输,每一个流都有唯一的标识,为了防止两个流ID冲突,客户端发起的流具有奇数ID,服务端发起的流具有偶数ID,所有的HTTP2通信都在一个TCP链接上完成,这个连接可以承载任意数量的双向数据流Stream。 相应地, 每个数据流以 消息的形式发送, 而消息由一 或多个帧组成, 这些帧可以乱序发送, 然后根据每个帧首部的流标识符重新组装。

image.png

举个例子,每个请求是一个数据流,数据流以消息的方式发送,而消息又分为多个帧,帧头部记录着stream id用来标识所属的数据流,不同属的帧可以在连接中随机混杂在一起。接收方可以根据stream id将帧再归属到各自不同的请求当中去。
另外,多路复用(连接共享)可能会导致关键请求被阻塞。HTTP2里每个数据流都可以设置优先级和依赖,优先级高的数据流会被服务器优先处理和返回给客户端,数据流还可以依赖其他的子数据流。
可见,HTTP2实现了真正的并行传输,它能够在一个TCP上进行任意数量HTTP请求。而这个强大的功能则是基于“二进制分帧”的特性。

宏观上看,基于二进制分帧层,htp2可以在共享TCP链接的基础上,同时发送请求和响应,HTTP消息被分解为独立的帧,交错发出,最后在另一端根据ID和首部将它们重新组合起来。
image.png

以上就是HTTP2主要的特点,接下来会是HTTP3的特点,未完待续。。。。


JeremyChen
2.1k 声望32 粉丝

本人前端工程师一名,技术不高,喜欢钻研,目前公司所用的前端技术是,webpack + express + react + redux 等构成的项目。希望能结识一帮喜好研究的朋友