鉴于 http1.0 已经基本被淘汰了,我也没有过多地关注1.0 的内容,而是从 http1.1 学起,这里只是一个知识点的梳理
1、http1.1
- 在以前的文章中提到,浏览器 是有专门的 网络进程的
- 在 http1.1 中,同一时间对于 同一个域名 只会保留 6 个 TCP 连接
- 在 请求中包含 keep-alive(浏览器默认给每个请求都加上了这个配置) 的前提下,请求会复用 之前的 TCP 连接
- 如果 不想 复用,可以再 请求头上 加上 Connection: close
- 在 http1.1 中,提供了 对虚拟主机的支持,也就是 在同一个 ip 下,还可以有不同的 主机,主要是 通过 host 的请求头配置
- 通过 chunk 机制来 动态地传输 要发送的内容,将 数据进行分割,携带上 每个数据块 的长度,在最后 发一个 长度为 0 的数据块 表示 发送结束
- 同时 还有 cookie、cache-control 等 新式的 请求头参数
但是 http1.1 还是有不少缺陷的
- TCP 启动太慢了,三次握手
- 开启了 多条的 TCP 之后,互相之间会竞争 带宽,当需要下载 重要的资源的时候,反而会导致 用户体验差,比如 js、css 这些会阻塞 渲染的 资源
- TCP 负责的请求还是太少了,如果前面的请求太慢,后面的请求就会一直等待
2、http2.0
很多 国外的网站都是使用了 http2,那么为什么要强调国外呢?
- 没错了 百度、淘宝 等 国内大型网站都还在使用 http1.1
- http2.0 最重要的 改进 在于 传输 的内容 都是 二进制字节流,而很多 的新特性 也是得益于 这个而发展出来的
- 多路复用,所谓多路复用,就是 这里 不再维持 6 个TCP 了,而是 对于一个 域名 维持 一个 TCP 连接
- 在传输的过程中,给每个数据块 加一个 对应 请求 的id,系统就可以根据 id 拼出来 想要的 返回结果
- 而在使用 多路复用 的前提下,就减少了 TCP 的连接,也减少了 三次握手的过程,自然也加快了速度
- 可以 设置请求的 优先级,比如 一个 网页中,js、css 的优先级 比较高,可以在多路复用的传输过程中,可以优先传输 这一类的文件
- http2.0 是可以实现 服务器推送的,那么 在 用户请求 一个html 之后,服务器可以主动把 js、css文件推过来,减少了 主动请求的过程,这样的话 用户体验自然更好
- http2.0 实现了 头部压缩,这个 没什么好多说的
- 对于 HTTP/2 来说,一个域名使用一个 TCP 连接才能够获得最佳性能,如果开多个域名,就会浪费带宽和服务器资源,也会降低 HTTP/2 的效率,所以“域名收缩”在 HTTP/2 里是必须要做的。
- “资源合并”在 HTTP/1 里减少了多次请求的成本,但在 HTTP/2 里因为有头部压缩和多路复用,传输小文件的成本很低,所以合并就失去了意义。而且“资源合并”还有一个缺点,就是降低了缓存的可用性,只要一个小文件更新,整个缓存就完全失效,必须重新下载。
http2.0 自然也是有缺陷的
在 TCP 连接中,由于 需要确保 请求发送出去了,那么 就会对 发送出的 包进行检验,如果发生了丢包的事情,就会 重新发送。
而在这个重新发送的过程中,所有的 请求都会停止,等待 这个丢掉的包成功发送
3、HTTP3.0
关于这个协议,我了解的也不多
- 这个协议是在 UDP 的基础上,重新实现的 QUIC 协议
- 集成了 TLS 加密的功能(https)
- 由于 基于 UDP ,就可以 握一次手,乃至于不握手了
4、https
- https 是在 http 协议和 TCP 协议之间,加上了 一层SSL/TLS 加密、解密的过程
- 先是进行了 TCP 的三次握手
- 现在 的 https 是对称加密(双方 握有相同的秘钥) 和 非对称加密(客户端握有 公钥,服务端握有 私钥) 的配合使用
- 浏览器 生成 一个 client-random 随机数 发送给 服务端(这里还会带上 可以使用的 加密算法列表)①
- 服务端 保存 client-random ,然后生成 一个 service-random 随机数,和 自己的数字证书 发送到 客户端(这里会 选择 第3点带上的 加密算法列表中的一个 返回给客户端 )②
- 数字 证书有 明文部分,有 密文部分,明文部分 是使用hash 加密的,而 密文部分 是 CA 机构 使用自己的私钥 加密的
- 客户端 接收到 数字证书之后,使用 系统 内嵌 的 证书公钥 解密 证书,获得摘要信息(这里还包括服务器 发送的 公钥信息),验证 服务端 的域名信息等相关信息(也就是 明文 部分 和密文 部分一致),知道了 这个服务端 确实是 我的服务端
- 客户端再生成 pre-random 随机数,利用 第6点 中提到的 公钥信息 进行加密后,发送给 服务端 ③
- 服务端 使用 私钥 解密,这样 客户端 和 服务端 就都保存了 三分随机数,client-random service-rendom pre-random ,用 约定好的 加密算法 (就是 第 3、4 点 客户端、服务端 选择的 加密算法) 计算出 相等的 对称加密 的秘钥
- 这样 就可以使用 生成 秘钥 进行加密数据 通讯了
- 所以 加上 TCP 的三次握手,HTTPS 一共经历了 6 次握手 才能够共享 一个密钥