03 - 说说 HTTP 之你不知道的知识

码不停息

共 4319字,需浏览 9分钟

 · 2021-12-12

你好我是刘小灰,这是我的第 03 篇原创文章。

前言

无论是前端开发工程师还是后端开发工程师,在工作中最常接触到的网络协议还是 http/https 协议,但是你真的了解 HTTP 吗?可以用以下问题进行自测:

  1. 为什么 HTTP 叫超文本传输协议
  2. HTTP 目前的版本是多少
  3. 一个浏览器同时可以发送多少个HTTP请求
  4. TCP 和 HTTP 有什么关系

如果你感觉这些问题都还OK,别急还有更加劲爆的问题

  1. 为什么 HTTP1.1 会出现对头阻塞
  2. HTTP2.0 优化哪些问题
  3. TCP 的队头阻塞是什么
  4. 什么是冷启动
  5. 为什么需要三次握手
  6. HTTPS 的加密方式是什么

如果你对以上问题磨轮两可,那这边文章可以极大的帮助你,如果你对上面的问题都胸有成竹,那可以换一个地方继续摸鱼啦!

HTTP 的发展历

纵观 HTTP 发展史,我们可以学到,任何技术都需要服务于业务,需求的变革从而影响技术的更新迭代,所以在我们平时做项目过程中 为了满足以后并不确定的需求从而把当前的项目架构弄的过于复杂 是不明智的。满足当前项目需求,保持一定的扩展性是项目架构设计的哲学。

HTTP/0.9

1990年初 HTML 被发明 HTTP/0.9 当时还没有 CSS 页面结构也极其简单。有了 HTML 后就自然有个需求就是如何传输 HTML,所以在 1991 HTTP/0.9 就被提出,专门用来传输 HTML 页面,所以又名 超文本传输协议

当时的 HTTP/0.9 设计的极其简单,简单到只有一个GET命令

GET /index.html

上面的命令就是用来获取服务器的index.html页面。同时协议规定,服务器只能回应HTML格式的字符串,不能回应别的格式。

HTTP/0.9 的极简风设计虽然简单,但一使用就是五年,直到五年后 HTTP1.0 才发布

题外话:马云第一次去美国见到互联网是1995年,那个时候还是 HTTP0.9 但是马云却笃定这就是未来,也许这就是远见以及魄力吧!

HTTP/1.0

随着互联网以及浏览器的发展,简单的 HTTP/0.9 已经不能满足现有需求,在1996年5月,HTTP/1.0 版本发布,大大丰富了 HTTP 协议,主要包括以下几个方面:

  1. 支持多种类型的文件下载,因为现在的页面已经不是简单的 HTML 了,还有 CSS 以及 JavaScript 等。
  2. 支持请求头和响应头,这样浏览器与服务器之间可做的事情就更多了(缓存设置,压缩设置,多语言设置等)
  3. 除了 GET 命令,还引入了 POST 命令和 HEAD 命令,以及引入了状态码

可以看出 HTTP1.0 可以说是一次重大更新,极大的丰富了 HTTP 协议

HTTP/1.1

1997年1月,HTTP/1.1 版本发布,只比 1.0 版本晚了半年。它进一步完善了 HTTP 协议,一直用到了20年后的今天,直到现在还是最流行的版本,其实本质来讲,HTTP/1.1 只是对 HTTP/1.0 做了优化,主要从以下几个方面:

  1. TCP 持久连接。在 HTTP1.0 中一个TCP管道上只能传输一个 HTTP 请求,并且传输完后就立即断开,这大大降低了传输效率,所以在 1.1 版本一个TCP连接中可以传输多个HTTP请求,并且只要浏览器或者服务器没有明确断开连接,那么该 TCP 连接会一直保持,并且浏览器为每个域名最多同时维护 6 个 TCP 持久连接
c72bf30f307596173cfc683072a4bae8.webpimage.png

关于 TCP 和 HTTP 的关系你可以简单的把 TCP 看作是电线的外壳,把 HTTP 看作是一根根被包裹的线,如上图所示。

  1. 完善请求头,比如新增 Host、Chunk transfe 字段等。
  2. 新增了 PUTPATCHHEAD、 OPTIONSDELETE 等请求命令。

到目前为止 HTTP/1.1 还是我们目前最常用的版本

任意打开一个网站,打开控制台,点击 View parsed 就可以看到 HTTP 版本号

f072ebbb07c3e5b4bd973ce42f9805a8.webpimage.png

HTTP/2.0

随着 Web 端的快速发展,很多应用都在使用 Web 技术实现,用户对页面的加载速度也有了更高的要求,而 HTTP/1.1 在网络带宽的利用以及在传输速度上并不理想,主要有以下问题:

  1. TCP 的慢启动

一个域名下系统会同时建立多个 TCP 请求(最多支持6个),那这么多 TCP 是怎么建立的呢?答案是三次握手(后面会讲到)。一听是三次握手,那肯定是需要花费时间的,还有就是 TCP 在建立成功后其运输数据会有一个慢启动的过程,就像你开车跑高速一样,从 0 到 120 码是一个逐步的过程,到了 120 后车子才保持最高速度行驶。

  1. 多个 TCP 会相互竞争带宽资源

一个页面可以建立多个 TCP 连接,但每个 TCP 连接要传输的资源又不一样,如 CSS 文件、JavaScript 文件等,而有的 TCP 连接下载的是图片、视频等普通的资源文件,但是多条 TCP 连接之间又不能协商让哪些关键资源优先下载,这样就有可能影响那些关键资源的下载速度了,导致不好的页面渲染效果。

  1. 队头阻塞

虽然在一个 TCP 连接中可以传输多个 HTTP 请求,但是 TCP 对请求的处理是同步的,也就是只能一个一个的处理,在一个 HTTP 请求没有结束前,其他请求都是处于阻塞状态,这大大影响我们的首屏渲染。

HTTP2.0 的出现就是为了优化 HTTP1.1 存在的以上问题,优化策略如下:

  1. 一个域名只能使用一个 TCP 连接

这样就可以保证 TCP 只会连接以及慢启动一次,同时也解决了竞争带宽的问题

  1. 多路复用

HTTP/2 实现了资源的并行请求,也就是任何时候都可以将请求发送给服务器,而并不需要等待其他请求的完成,然后服务器也可以随时返回处理好的请求资源给浏览器

  1. 请求优先级

HTTP/2 提供了请求优先级,可以在发送请求时,标上该请求的优先级,这样服务器接收到请求之后,会优先处理优先级高的请求。

HTTP/2 的瓶颈在哪里

TCP队头阻塞

看上去 HTTP/2 真是个完美的协议,但是不要忘了,HTTP2 是基于 TCP 的上层协议,而 TCP 本身也存在队头阻塞问题。如果在数据传输过程中,一个数据包不小心丢掉了,那整个TCP连接就会处于暂停状态,直到丢失的数据包被重新传输过来

由于 HTTP2 在一个域名下只会创建一个TCP 连接,所以一旦丢包出现的概率增加就会大大影响数据传输效率。有测试数据表明,当系统达到了 2% 的丢包率时,HTTP/1.1 的传输效率反而比 HTTP/2 表现得更好。

TCP 三次握手

我们总是在说 TCP 三次握手,下面我们就来看看什么是三次握手,以及为什么需要三次握手。

如果想让客户端和服务器之间可以传输数据,首先就得建立 TCP 连接,那怎样才能证明建立上连接了呢?这就需要服务端和客户端 分别确认 对方可以发送和接受数据,这个确认的过程就是俗称握手。

f0b0f452443606e2e600cffc82023587.webpimage.png

第一次握手:服务器可以确认客服端有发送消息的能力

第二次握手:客户端可以确认服务端有发消息能力,以及客户端可以确认服务可以接收消息的能力

第三次握手:服务端可以确认客户端有接收消息的能力

经过三次握手后,客户端和服务端都证明了自己即可以发送消息又可以接收消息,自此连接建立成功。

那为什么不是四次握手呢?四次当然可以,但是既然三次就可以确认了为什么要再浪费一次数据传输资源呢?

正是因为有这个双方确认的过程,所以也增加了整个数据的传输时长,真是可谓鱼和熊掌不可兼得。

HTTP/3

由于 TCP 协议的局限性,所以 HTTP/3 打算彻底甩掉历史包袱,使用一个全新的协议 QUIC 协议。但是路漫漫其修远兮,历史包袱真的就那么容易甩掉吗?那就不得而知了。

为什么需要HTTPS

如果单纯从整个物理时间来看,我认为 HTTP 是安全的,因为它看不见摸不着,普通人也不会关注它是如何传输数据的,人们只会关心自家的网速够不够快,视频看着卡不卡顿。

但是从虚拟世界来看,总会有一些人游离在数据之上寻找着各种快乐,我们称他们为黑客。而从某种意义上来讲,黑客也可能是这个虚拟世界的创造者。

总之 HTTP 作为明文传输,就像是在公路上裸奔的美女一样极不安全,我们需要一种方式来伪装自己,对于数据来说,伪装自己最有效的方式就是加密。

对称加密

对称加密就是加密和解密使用的密钥是一样的,比如我也可以自己规定一种加密方式,如下所示:


// 密钥
var secretKey = 666

// 加密方法
function encrypt(val){
    return val * 666
}
// 解密方法
function deciphering(val){
    return val/666
}

这种加密方式运用在客户端与服务器数据传输安全吗,显然是不安全的,因为密钥也需要被传输,而且是明文传输。

非对称加密

非对称加密就是使用公钥加密的数据只能用私钥解密,使用私钥加密的数据只能用公钥解密。

比如现在浏览器有公钥(可公开),服务器有私钥(不公开),数据传输如下:

48ba0f7a0b32f9d623056166655c3f01.webpimage.png

从上图中我们可以看到,客户端可以使用公钥进行加密服务端使用私钥解密,但是服务端给客户端发数据时就不能进行加密了,因为客户端只有公钥,服务端只有私钥,如果要加密,服务端只能把私钥也传给客户端,客户端才能解密,这样显然没什么意义了。

HTTPS采用的加密方式

既然对称和非对称加密都不安全,那 HTTPS 是使用什么加密方式呢?答案是 在传输数据阶段依然使用对称加密,但是对称加密的密钥我们采用非对称加密来传输

如下图所示:(实际流程复杂的多,这里为了便于理解只演示核心流程)

bc570a50d81c1ddef3cb1d343eb5949c.webpimage.png

使用了对称和非对称加密相结合后数据可以被安全的传输了,现在数据是安全了,但是并不能保证我们访问的站点安全。也就是黑客可以通过 DNS 劫持,把用户要访问的站点直接换成其他站点。那这个问题如何解决呢?

答案是添加数字证书,就是让服务器像浏览器证明 “我就是我”。而且对称加密的密钥也被存放在数字证书里面。

这样以来,即使 DNS 被劫持了,但是假的服务器并不能提供对应的数据证书(不能伪造),自然就建立不了连接。

总结

总的来说 HTTP 作为应用层协议,一直紧跟着互联网的发展。也正是因为 HTTP 的存在才造就了互联网繁荣的生态,社会的进步推动技术的进步,在这个世界上没有完美的技术,也没有完美的解决方案,有的时候适合当前就是最优解。

最后

如果这篇文章对你有帮助,别忘赏个赞👍。

参考文献:HTTP 协议发展历史浏览器工作原理与实践 什么是DNS


浏览 18
点赞
评论
收藏
分享

手机扫一扫分享

举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

举报