http协议的历史

·  阅读 165

http0.9--只需要下载HTML文件

超文本传输协议,完整请求流程:

  1. 客户端根据IP地址、端口号和服务器建立tcp连接.(3次握手)
  2. 建立好连接后,会发送一个GET请求行的信息,如GET /index.html用来获取index.html
  3. 服务器接收请求信息之后,读取对应的HTML文件,并将数据以ASCII字符流返回客户端。
  4. HTML文档传输完成后,断开连接。(4次挥手)

当时的需求很简单,传输体积很小的HTML文件,所以http0.9有三个特点:

  1. 第一个是只有一个请求行,并没有http请求头和请求体,因为只需要一个请求行就可以完整表达客户端的需求。
  2. 第二个是服务器也没有返回头信息,这是因为服务器并不需要告诉客户端太多的信息,只需要返回数据就可以了。
  3. 第三个是返回的文件内容是以ASCII字符流来传输的,因为都是HTML格式的文件,所以使用ASCII字节码来传输是最合适的。

http1.0--需要支持多种格式的文件

在浏览器中不单展示HTML文件,还有js、CSS、图片、音频等。

支持多种类型的文件下载是http1.0的一个核心诉求,因此文件格式不仅局限于ASCII编码,还有其他。加入请求头和响应头、请求行和响应行。

要支持多类型文件,还需解决以下问题:

  1. 浏览器要知道服务器返回的数据是什么类型的。accept:text/html
  2. 由于单个文件数据量越来越大,为了减轻传输性能,服务器会对数据进行压缩后再传输,所以浏览器需要知道服务器的压缩方法。accept-encoding:gzip
  3. 浏览器告诉服务器,它想要什么语言版本的页面。accept-language:zh
  4. 浏览器需要知道文件的编码类型。accept-charset:utf-8

除此之外,还引入了状态吗、cache机制、用户代理(服务器统计客户端的基础信息)

http1.1

  1. 原先http1.0每次进行http通信,都要经历建立tcp连接、传输http数据和断开tcp连接三个阶段。http1.1改进为持久连接,connection:keep-alive。持久连接在http1.1默认开始,通过connection:close关闭。目前chrome浏览器对于同一个域名,默认允许同时建立6个tcp连接。我们可以通过增加域名来增加tcp连接的数量。

  2. 不成熟的http管线化(放弃了)

    持久连接虽然能减少tcp的连接和断开,但是它需要等待前面的请求返回之后,才能进行下一次请求。如果tcp通道中某个请求由于某个原因没有及时返回,那么就会阻塞后面的请求,形成队头阻塞的问题。

    http1.1试图通过管线化得技术来解决队头阻塞的问题,将多个http请求打包提交给服务器,虽然可以整批发送请求,但是服务器依然需要根据请求顺序来回复浏览器。

    firfox、Chrome都做过http管线化得尝试,最后都放弃了。

  3. 提供虚拟主机的支持

    在http1.0,每个域名都绑定了一个唯一的IP地址,因此一个服务器只能支持一个域名。

    为了支持多个域名公用一个IP地址,http1.1请求头中新增了Host字段,用来表示当前域名地址,服务器通过不同的Host值来返回不同的数据。

  4. 对动态生成的内容提供完美支持

    http1.0中,需要在响应头中设置完整的数据大小,如content-length:900,这样浏览器就可以根据设置的数据大小知道何时接收完数据了。

    但是随着服务器技术的发展,很多内容都是动态生成的,无法预先知道传输数据的大小。

    http1.1通过引入Chunk transfer机制来解决这个问题,服务器会将数据分割成若干个任意大小的数据块,每个数据块发送时会附上上一个数据块的大小,最后使用一个零长度的数据块来表示数据传输完毕,这样就提供了动态内容的支持。

  5. 客户端cookie机制、安全机制

http2.0

http1.1对带宽的利用率不理想,主要是以下三个原因导致的:

  1. tcp连接的慢启动(tcp连接本身固有的问题)
  2. http1.1的多条tcp连接竞争带宽
  3. http1.1的队头阻塞

http2.0的解决方法是一个域名只启动一个tcp连接和消除队头阻塞。

通过多路复用技术来消除队头阻塞问题。

通过引入二进制分帧层来实现http2.0的多路复用技术。

http2.0的请求和接收过程:

  1. 浏览器准备好请求数据,包括请求行,请求头等信息。如果是post方法,那么还有请求体。
  2. 这些数据经过二进制分帧层处理之后,会被转换为一个个带有请求ID编号的帧,通过协议栈将这些帧发送给服务器。
  3. 服务器接收到所有帧之后,会将相同ID编号的帧合并为一条完整的请求信息。
  4. 然后处理该请求,并将响应数据,包括响应头,响应行,响应体,发送给二进制分帧层。
  5. 同样,二进制分帧层将这些响应数据转换为到带有ID编号的帧,经过协议栈发送给浏览器。
  6. 浏览器接收到这些帧之后,会将相同ID编号的帧合并提交给对应的请求。

http2.0的其他特性:

  1. 设置请求的优先级??怎么设置呢
  2. 服务器推送
  3. 头部压缩

http3.0--路还很长

http3另起炉灶,使用了QUIC协议,这个协议集各家之所长,集成了tcp+http2的多路复用+https的tls。

https

在浏览器安全中再介绍。

三次握手、四次挥手

tcp连接为什么要有3次握手?2次不行吗?

当客户端C给服务端S发送一个消息,如果是2次握手,而客户端C这边由于某个原因断开了,而服务端S却还在苦苦等待传输。这样就造成了服务器资源的浪费。

2次握手的话,在服务端这边,它并没有确认自己的发送能力,以及客服端的接收能力。(向客户端发送了,但是不知道客户端收没收到,所以不确定自己的发送能力,以及客户端的接收能力)

为什么断开的时候是4次挥手?从宏观角度分析:

  1. 主动关闭方A告诉被动关闭方B,我这边发送数据完毕了;

  2. 被动关闭方B,告诉主动 关闭方A,我这边数据也发送完毕了;

  3. 被动关闭方B,告诉主动关闭方A,我这边数据接收完毕了;

  4. 主动关闭方A告诉被动关闭方B,我这边数据接收完毕;

本文参考极客时间李兵老师的浏览器工作原理与实践。

分类:
前端
标签:
分类:
前端
标签:
收藏成功!
已添加到「」, 点击更改