03 - 说说 HTTP 之你不知道的知识
你好我是刘小灰,这是我的第 03 篇原创文章。
前言
无论是前端开发工程师还是后端开发工程师,在工作中最常接触到的网络协议还是 http/https
协议,但是你真的了解 HTTP 吗?可以用以下问题进行自测:
- 为什么 HTTP 叫超文本传输协议
- HTTP 目前的版本是多少
- 一个浏览器同时可以发送多少个HTTP请求
- TCP 和 HTTP 有什么关系
如果你感觉这些问题都还OK,别急还有更加劲爆的问题
- 为什么 HTTP1.1 会出现对头阻塞
- HTTP2.0 优化哪些问题
- TCP 的队头阻塞是什么
- 什么是冷启动
- 为什么需要三次握手
- 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 协议,主要包括以下几个方面:
- 支持多种类型的文件下载,因为现在的页面已经不是简单的
HTML
了,还有CSS
以及JavaScript
等。 - 支持请求头和响应头,这样浏览器与服务器之间可做的事情就更多了(缓存设置,压缩设置,多语言设置等)
- 除了
GET
命令,还引入了POST
命令和HEAD
命令,以及引入了状态码
可以看出 HTTP1.0
可以说是一次重大更新,极大的丰富了 HTTP 协议
HTTP/1.1
1997年1月,HTTP/1.1
版本发布,只比 1.0 版本晚了半年。它进一步完善了 HTTP
协议,一直用到了20年后的今天,直到现在还是最流行的版本,其实本质来讲,HTTP/1.1
只是对 HTTP/1.0
做了优化,主要从以下几个方面:
- TCP 持久连接。在
HTTP1.0
中一个TCP管道上只能传输一个HTTP
请求,并且传输完后就立即断开,这大大降低了传输效率,所以在 1.1 版本一个TCP连接中可以传输多个HTTP请求,并且只要浏览器或者服务器没有明确断开连接,那么该 TCP 连接会一直保持,并且浏览器为每个域名最多同时维护 6 个 TCP 持久连接。
关于 TCP 和 HTTP 的关系你可以简单的把 TCP 看作是电线的外壳,把 HTTP 看作是一根根被包裹的线,如上图所示。
- 完善请求头,比如新增 Host、Chunk transfe 字段等。
- 新增了
PUT
、PATCH
、HEAD
、OPTIONS
、DELETE
等请求命令。
到目前为止 HTTP/1.1
还是我们目前最常用的版本
任意打开一个网站,打开控制台,点击 View parsed
就可以看到 HTTP
版本号
HTTP/2.0
随着 Web 端的快速发展,很多应用都在使用 Web 技术实现,用户对页面的加载速度也有了更高的要求,而 HTTP/1.1 在网络带宽的利用以及在传输速度上并不理想,主要有以下问题:
- TCP 的慢启动
一个域名下系统会同时建立多个 TCP 请求(最多支持6个),那这么多 TCP 是怎么建立的呢?答案是三次握手(后面会讲到)。一听是三次握手,那肯定是需要花费时间的,还有就是 TCP 在建立成功后其运输数据会有一个慢启动的过程,就像你开车跑高速一样,从 0 到 120 码是一个逐步的过程,到了 120 后车子才保持最高速度行驶。
- 多个 TCP 会相互竞争带宽资源
一个页面可以建立多个 TCP 连接,但每个 TCP 连接要传输的资源又不一样,如 CSS 文件、JavaScript 文件等,而有的 TCP 连接下载的是图片、视频等普通的资源文件,但是多条 TCP 连接之间又不能协商让哪些关键资源优先下载,这样就有可能影响那些关键资源的下载速度了,导致不好的页面渲染效果。
- 队头阻塞
虽然在一个 TCP 连接中可以传输多个 HTTP 请求,但是 TCP 对请求的处理是同步的,也就是只能一个一个的处理,在一个 HTTP 请求没有结束前,其他请求都是处于阻塞状态,这大大影响我们的首屏渲染。
而 HTTP2.0
的出现就是为了优化 HTTP1.1
存在的以上问题,优化策略如下:
- 一个域名只能使用一个 TCP 连接
这样就可以保证 TCP 只会连接以及慢启动一次,同时也解决了竞争带宽的问题
- 多路复用
HTTP/2
实现了资源的并行请求,也就是任何时候都可以将请求发送给服务器,而并不需要等待其他请求的完成,然后服务器也可以随时返回处理好的请求资源给浏览器
- 请求优先级
HTTP/2
提供了请求优先级,可以在发送请求时,标上该请求的优先级,这样服务器接收到请求之后,会优先处理优先级高的请求。
HTTP/2 的瓶颈在哪里
TCP队头阻塞
看上去 HTTP/2
真是个完美的协议,但是不要忘了,HTTP2 是基于 TCP 的上层协议,而 TCP 本身也存在队头阻塞问题。如果在数据传输过程中,一个数据包不小心丢掉了,那整个TCP连接就会处于暂停状态,直到丢失的数据包被重新传输过来。
由于 HTTP2 在一个域名下只会创建一个TCP 连接,所以一旦丢包出现的概率增加就会大大影响数据传输效率。有测试数据表明,当系统达到了 2% 的丢包率时,HTTP/1.1 的传输效率反而比 HTTP/2 表现得更好。
TCP 三次握手
我们总是在说 TCP 三次握手,下面我们就来看看什么是三次握手,以及为什么需要三次握手。
如果想让客户端和服务器之间可以传输数据,首先就得建立 TCP 连接,那怎样才能证明建立上连接了呢?这就需要服务端和客户端 分别确认 对方可以发送和接受数据,这个确认的过程就是俗称握手。
image.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
}
这种加密方式运用在客户端与服务器数据传输安全吗,显然是不安全的,因为密钥也需要被传输,而且是明文传输。
非对称加密
非对称加密就是使用公钥加密的数据只能用私钥解密,使用私钥加密的数据只能用公钥解密。
比如现在浏览器有公钥(可公开),服务器有私钥(不公开),数据传输如下:
image.png从上图中我们可以看到,客户端可以使用公钥进行加密服务端使用私钥解密,但是服务端给客户端发数据时就不能进行加密了,因为客户端只有公钥,服务端只有私钥,如果要加密,服务端只能把私钥也传给客户端,客户端才能解密,这样显然没什么意义了。
HTTPS采用的加密方式
既然对称和非对称加密都不安全,那 HTTPS 是使用什么加密方式呢?答案是 在传输数据阶段依然使用对称加密,但是对称加密的密钥我们采用非对称加密来传输。
如下图所示:(实际流程复杂的多,这里为了便于理解只演示核心流程)
image.png使用了对称和非对称加密相结合后数据可以被安全的传输了,现在数据是安全了,但是并不能保证我们访问的站点安全。也就是黑客可以通过 DNS 劫持,把用户要访问的站点直接换成其他站点。那这个问题如何解决呢?
答案是添加数字证书,就是让服务器像浏览器证明 “我就是我”。而且对称加密的密钥也被存放在数字证书里面。
这样以来,即使 DNS 被劫持了,但是假的服务器并不能提供对应的数据证书(不能伪造),自然就建立不了连接。
总结
总的来说 HTTP 作为应用层协议,一直紧跟着互联网的发展。也正是因为 HTTP 的存在才造就了互联网繁荣的生态,社会的进步推动技术的进步,在这个世界上没有完美的技术,也没有完美的解决方案,有的时候适合当前就是最优解。
最后
如果这篇文章对你有帮助,别忘赏个赞👍。
参考文献:HTTP 协议发展历史浏览器工作原理与实践 什么是DNS