极简HTTP史

266 阅读7分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第5天,点击查看活动详情

前言: 前段时间学校的课程里面讲了 HTTP 相关的知识,在好奇心的驱使下也潦草的翻阅了《图解HTTP》 这本书,当时读的时候一知半解的,有那么多的头头、那么多协议,看的我是眼花缭乱的。经过一段时间的遗忘后,就把这些知识归还给书本了。遂痛定思痛,下了决心要学一学 HTTP,于是了解了一点 HTTP 的相关历史,以便更好的理解 HTTP 相关的知识,于是写下了本文。

什么是HTTP

官方的说:http(Hypertext transfer protocol)超文本传输协议,通过浏览器和服务器进行数据交互,进行超文本(文本、图片、视频等)传输的规定。

Http 0.9

最初始的时候就是0.9版本,当时主要用于各大实验室进行传递html的超文本内容给客户端,它的实现也就是客户端请求,服务端进行相应的一个模式。其过程主要如下:

客户端 --> dns查询ip地址 -->建立tcp链接 -->客户端发起请求 -->服务端响应 -->断开tcp连接

该版本具有如下三个特点:

  1. 客户端只有一个请求,没有请求头与请求体。
  2. 服务端没有返回头信息。
  3. 服务端返回的内容以ask码字符流的形式传输。

HTTP 1.0 (支持多种类型的下载和传输)

1.0 版本是被动的被浏览器推动更新的。随着万维网的发展一发不可收拾,此时就带来了很多的需求比如需要传输如 js、css 等资源,而此时 0.9版本 只能传输html的超文本协议,所以1.0 最主要的一个目的就是带来更多编码格式文件的传输。与此同时在建立连接之后,浏览器在发送请求的时候只能发送类似于 get 这样简单的请求命令,并不能告诉服务器更多的信息,所以就引入请求头和响应头(key-value的形式)。这样浏览器与服务器就可以加上请求头或者响应头来告诉对方自己需要什么。

此时客户端与服务端请求的流程:

客户端--> dns --> 建立tcp连接 -- 客户端发起请求(包含请求行、请求头)--服务端响应(包含响应头、响应体)--> 断开tcp连接

在引入请求头与响应头之后,怎么支持多种类型的数据?

  1. 浏览器要知道服务器返回的文件类型是什么
  2. 浏览器要知道服务器压缩文件的方法 (此时文件可能很大了)
  3. 浏览器要知道服务器返回的语言版本 (不同地区语言版本)
  4. 浏览器要知道服务器返回文件的编码类型

请求头内的内容:

  • accetp: text/html
  • accept-encoding: gzip, deflate, br
  • accept-language: zh-CN,zh
  • accept-Charset: ISO-8859-1, utf-8 ...

响应头内的内容:

  • content-encoding: br
  • content-type: text/html;charset=UTF-8 ...

同时 1.0 还添加了如:状态码、Cache机制 (缓存机制)、用户代理等机制。

总结: http 1.0 主要就是用来实现多种文件的传输,同时还添加了如:状态码Cache机制 等机制

HTTP 1.1

随着技术的蓬勃发展,很多需求 1.0 版本又不能支持。随着硬件设备的更新,传输的文件大小也在不断的增大,同时一个页面里面可能引用了上百个资源,在引用这些资源的时候就需要不断的重复向资源请求连接断开连接。这样就带来了性能的开销过大问题,所以 1.1 版本就引入了---- 持久化连接。此时浏览器对于同一个域名默认只支持6个TCP连接。

新增内容:

1. 持久化连接:只要浏览器或者服务器没有明确表示要断开连接,那么这个TCP连接就会一直保持。

2. 队头阻塞:持久连接就会导致在建立TCP连接后,如:TCP http http http http http http TCP(http 表示一个请求)这样一次浏览器与服务器通信,如果第一个 http 没有执行完,那么就会阻塞后续的所以 http 请求。

3. 提供虚拟主机的支持:1.1 版本新增了提供虚拟主机(一个虚拟主机一个域名)的支持的功能,允许一个域名绑定一个ip地址的多个域名。

4. 动态生成的内容

5. cookie、安全机制

http 1.1 存在的缺陷:带宽用不满

原因:

  1. TCP的慢启动 ( 刚开始建立tcp连接就会用非常慢的速度进行数据发送,然后慢慢增加速度,相当于汽车启动的过程) (为了减少网络拥塞)
  2. 同时启动多条TCP连接,会相互竞争带宽
  3. 队头阻塞

HTTP 2.0 (多路复用技术)

上面说 HTTP1.1 版本存在着带宽用不满的情况,所以 2.0 版本就来解决这个问题,也就是多路复用技术 (二进制分帧层 最重要的技术,就是将请求分成很多一帧的碎片) 用来解决带宽不满的问题。此时 HTTP 2.0 只允许: 一个域名只使用一个TCP长连接, 这样就只让 TCP 的慢启动执行一次,也避免了上面的第二个问题,但是这样就会加重队头阻塞问题。所以现在要解决的问题就是如何让 HTTP 建立了一个连接,解决掉队头阻塞问题。

解决方案:

  • 多路复用:将请求分成一帧一帧的数据进行传输,让所有的http 请求并行发送。

当然 2.0 还增加了

  • 可以设置请求的优先级

  • 服务器推送:将数据提前推送到浏览器

  • 对请求头以及响应头进行压缩

HTTP 2.0 存在的缺陷: 1. TCP的队头阻塞,多路复用虽然优化了这个问题,但是也没有完全解决掉根本。 2. 传输效率 (tcp握手影响)

HTTP 3.0 -- UDP

HTTP 3.0 以前的版本都是建立于 TCP 之上架构的,但是 TCP 存在的队头阻塞本质上还是无法解决,只要出现丢包,那么后续的请求就会一定等待该份数据重新传输过来才会继续传输。所以解决 TCP 缺陷就是绕过 TCP 协议。所以 HTTP 3.0 是基于 UDP 实现的,HTTP 3.0 的核心是QUIC协议。

UDP

UDP 协议是面向无连接的,就好像一根水管,只是数据报文的搬运工,其不保证数据的有序传输且不保证数据不丢包。UDP 并不需要像TCP一样建立连接才可以发送数据,它只是数据的搬运工,不会对数据进行拆分等操作。

UDP 特点

  1. 不可靠性:对于数据想发就发,不用建立连接,而且没有流量拥塞控制。
  2. 高效:它的不可靠性也就造就了它传输的高效性,它并不需要像TCP一样有效的传输数据。
  3. 传输方式:支持一对多、多对多、多对一、一对一的传输方式。

至始至终 UDP 的优点就是高效,传输速度快。

QUIC 协议

  1. 实现了类似于tcp的流量控制、传输的可靠性
  2. 集成了TLS 加密功能
  3. 实现了HTTP2.0中的多路复用
  4. 实现了快速握手

后记: 请各位多多指教,这篇文章是我学习的总结,当然可能有些错误的地方没有及时发现,尊请赐教斧正🤝