超文本传输协议 HTTP/0.9
HTTP/0.9 主要用于学术交流,需求很简单,用来在网络之间传递HTML超文本的内容,所以被称为 超文本传输协议。
采用了基于请求响应的模式,从客户端发出请求,服务端返回数据。
被浏览器推动的 HTTP/1.0
需要支持多种类型的文件下载是HTTP/1.0的一个核心诉求,而且文件格式不仅仅局限于ASCII编码,还有很多其他类型的格式。
如何实现多种类型文件的下载?
HTTP/1.0引入了请求头和响应头,以Key-value形式保存的。发送会带上请求头信息,服务器返回数据时,会先返回响应头信息。
accept: text/html
accept-encoding: gzip, deflate, br
accept-Charset: ISO-8859-1,utf-8
accept-language: zh-CN,zh
还提供其他特性
- 状态码
- Cache 机制
-
缝缝补补的HTTP/1.1
改进持久连接。 http/1.0每次进行一次http通信,都需要建立tcp连接 传输 断开 tcp。HTTP/1.1 中增加了持久连接的方法,它的特点是在一个 TCP 连接上可以传输多个 HTTP 请求,只要浏览器或者服务器没有明确断开连接,那么该 TCP 连接会一直保持。
- 不成熟的http管线化
- 提供虚拟主机的支持。 HTTP/1.1的请求头 增加了 Host字段,用来表示当前的域名地址,这样服务器就可以根据不同的Host值做不同的处理。
- 对动态生成的内容提供了完美的支持。http/1.0 Content-Length http/1.1Chunk transfer机制。服务器会将数据分割成若干个任意大小的数据块,每个数据块发送时会附上上个数据块的长度,最后使用一个零长度的块作为发送数据完成的标志。这样就提供了对动态内容的支持
-
HTTP/2:如何提升网络速度
HTTP/1.1为网络效率做了大量的优化,最核心的有如下三种方式:
增加了持久连接 虽然公用一个TCP管道,但是在一个管道中同一时刻只能处理一个请求,在当前的请求没有结束之前,其他的请求只能处于阻塞状态。这意味着我们不能随意在一个管道中发送请求和接收内容。
- 浏览器为每个域名最多同时维护6个TCP持久连接
-
HTTP/1.1的主要问题
HTTP/1.1对带宽的利用率却不理想。带宽是指每秒最大能发送或者接受的字节数。 原因如下:
TCP的慢启动。一旦一个 TCP 连接建立之后,就进入了发送数据状态,刚开始 TCP 协议会采用一个非常慢的速度去发送数据,然后慢慢加快发送数据的速度,直到发送数据的速度达到一个理想状态,我们把这个过程称为慢启动。html css js这些关键文件在TCP连接建立好之后就要发起请求。但由于慢启动 耗费的时间比正常的时间要多很多。
- 同时开启了多条TCP连接,那么这些连接会竞争固定带宽。这样就会出现一个问题,因为有的 TCP 连接下载的是一些关键资源,如 CSS 文件、JavaScript 文件等,而有的 TCP 连接下载的是图片、视频等普通的资源文件,但是多条 TCP 连接之间又不能协商让哪些关键资源优先下载,这样就有可能影响那些关键资源的下载速度了。
HTTP/1.1队头阻塞的问题。在 HTTP/1.1 中使用持久连接时,虽然能公用一个 TCP 管道,但是在一个管道中同一时刻只能处理一个请求,在当前的请求没有结束之前,其他的请求只能处于阻塞状态。这意味着我们不能随意在一个管道中发送请求和接收内容。队头阻塞使得这些数据不能并行请求,所以队头阻塞是很不利于浏览器优化的。
HTTP/2的多路复用
HTTP/2 最核心、最重要且最具颠覆性的多路复用机制。从图中你会发现每个请求都有一个对应的 ID,如 stream1 表示 index.html 的请求,stream2 表示 foo.css 的请求。这样在浏览器端,就可以随时将请求发送给服务器了。
服务器端接收到这些请求后,会根据自己的喜好来决定优先返回哪些内容,比如服务器可能早就缓存好了 index.html 和 bar.js 的响应头信息,那么当接收到请求的时候就可以立即把 index.html 和 bar.js 的响应头信息返回给浏览器,然后再将 index.html 和 bar.js 的响应体数据返回给浏览器。之所以可以随意发送,是因为每份数据都有对应的 ID,浏览器接收到之后,会筛选出相同 ID 的内容,将其拼接为完整的 HTTP 响应数据。
HTTP/2 使用了多路复用技术,可以将请求分成一帧一帧的数据去传输,这样带来了一个额外的好处,就是当收到一个优先级高的请求时,比如接收到 JavaScript 或者 CSS 关键资源的请求,服务器可以暂停之前的请求来优先处理关键资源的请求。多路复用的实现
HTTP/2其他特性
可以设置请求优先级
- 服务端推送
-
HTTP/3:甩掉TCP TLS的包袱,构建高效的网络
HTTP/2缺陷
TCP的队头阻塞
你可以把 TCP 连接看成是两台计算机之前的一个虚拟管道,计算机的一端将要传输的数据按照顺序放入管道,最终数据会以相同的顺序出现在管道的另外一头。
不过,如果在数据传输的过程中,有一个数据因为网络故障或者其他原因而丢包了,那么整个 TCP 的连接就会处于暂停状态,需要等待丢失的数据包被重新传输过来。你可以把 TCP 连接看成是一个按照顺序传输数据的管道,管道中的任意一个数据丢失了,那之后的数据都需要等待该数据的重新传输
在 TCP 传输过程中,由于单个数据包的丢失而造成的阻塞称为 TCP 上的队头阻塞。队头阻塞怎么影响HTTP/2
通过该图,我们知道在 HTTP/2 中,多个请求是跑在一个 TCP 管道中的,如果其中任意一路数据流中出现了丢包的情况,那么就会阻塞该 TCP 连接中的所有请求。这不同于 HTTP/1.1,使用 HTTP/1.1 时,浏览器为每个域名开启了 6 个 TCP 连接,如果其中的 1 个 TCP 连接发生了队头阻塞,那么其他的 5 个连接依然可以继续传输数据。
所以随着丢包率的增加,HTTP/2 的传输效率也会越来越差。有测试数据表明,当系统达到了 2% 的丢包率时,HTTP/1.1 的传输效率反而比 HTTP/2 表现得更好。TCP建立连接的延迟
除了 TCP 队头阻塞之外,TCP 的握手过程也是影响传输效率的一个重要因素。
RTT(Round Trip Time)
那建立 TCP 连接时,需要花费多少个 RTT 呢?下面我们来计算下。
我们知道 HTTP/1 和 HTTP/2 都是使用 TCP 协议来传输的,而如果使用 HTTPS 的话,还需要使用 TLS 协议进行安全传输,而使用 TLS 也需要一个握手过程,这样就需要有两个握手延迟过程。 在建立 TCP 连接的时候,需要和服务器进行三次握手来确认连接成功,也就是说需要在消耗完 1.5 个 RTT 之后才能进行数据传输。
- 进行 TLS 连接,TLS 有两个版本——TLS1.2 和 TLS1.3,每个版本建立连接所花的时间不同,大致是需要 1~2 个 RTT,关于 HTTPS 我们到后面到安全模块再做详细介绍。
总之,在传输数据之前,我们需要花掉 3~4 个 RTT。如果浏览器和服务器的物理距离较近,那么 1 个 RTT 的时间可能在 10 毫秒以内,也就是说总共要消耗掉 30~40 毫秒。这个时间也许用户还可以接受,但如果服务器相隔较远,那么 1 个 RTT 就可能需要 100 毫秒以上了,这种情况下整个握手过程需要 300~400 毫秒,这时用户就能明显地感受到“慢”了。
TCP协议的僵化
中间设备的僵化
操作系统也是导致 TCP 协议僵化的另外一个原因。因为 TCP 协议都是通过操作系统内核来实现的,应用程序只能使用不能修改。通常操作系统的更新都滞后于软件的更新,因此要想自由地更新内核中的 TCP 协议也是非常困难的
QUIC协议
基于 UDP 实现了类似于 TCP 的多路数据流、传输可靠性等功能,我们把这套功能称为 QUIC 协议
通过上图我们可以看出,HTTP/3 中的 QUIC 协议集合了以下几点功能。实现了类似 TCP 的流量控制、传输可靠性的功能。虽然 UDP 不提供可靠性的传输,但 QUIC 在 UDP 的基础之上增加了一层来保证数据可靠性传输。它提供了数据包重传、拥塞控制以及其他一些 TCP 中存在的特性
- 集成了 TLS 加密功能。目前 QUIC 使用的是 TLS1.3,相较于早期版本 TLS1.3 有更多的优点,其中最重要的一点是减少了握手所花费的 RTT 个数。
- 实现了 HTTP/2 中的多路复用功能。和 TCP 不同,QUIC 实现了在同一物理连接上可以有多个独立的逻辑数据流(如下图)。实现了数据流的单独传输,就解决了 TCP 中队头阻塞的问题。
实现了快速握手功能。由于 QUIC 是基于 UDP 的,所以 QUIC 可以实现使用 0-RTT 或者 1-RTT 来建立连接,这意味着 QUIC 可以用最快的速度来发送和接收数据,这样可以大大提升首次打开页面的速度。
HTTP/3 的挑战
第一,从目前的情况来看,服务器和浏览器端都没有对 HTTP/3 提供比较完整的支持。Chrome 虽然在数年前就开始支持 Google 版本的 QUIC,但是这个版本的 QUIC 和官方的 QUIC 存在着非常大的差异。
第二,部署 HTTP/3 也存在着非常大的问题。因为系统内核对 UDP 的优化远远没有达到 TCP 的优化程度,这也是阻碍 QUIC 的一个重要原因。
第三,中间设备僵化的问题。这些设备对 UDP 的优化程度远远低于 TCP,据统计使用 QUIC 协议时,大约有 3%~7% 的丢包率。HTTPS:让数据传输更安全
浏览器安全主要划分为三大块内容:页面安全 系统安全 网络安全。
我们使用HTTP传输的内容很容易被中间人窃取 伪造和篡改,通常我们把这种攻击方式称为 中间人攻击。
在HTTP协议栈中引入安全层
总的来说,安全层有两个主要的职责:对发起HTTP请求的数据加密操作和对接受到HTTP的内容进行解密操作。对称加密
加密套件是指加密的方法,加密套件列表就是指浏览器能支持多少种加密方法。
使用非对称加密
非对称加密算法有A B两把密钥,如果你用A密钥加密,那么只能使用B密钥来解密;反过来,如果你要B密钥加密,那么只能用A密钥来解密。
公钥匙每个人都能获取到的,而私钥只有服务器才能知道,不对任何人公开。
非对称加密的效率太低
无法保证服务器发送给浏览器的数据安全。对称加密和对称加密搭配使用
首先浏览器向服务器发送对称加密套件列表、非对称加密套件列表和随机数 client-random;
- 服务器保存随机数 client-random,选择对称加密和非对称加密的套件,然后生成随机数 service-random,向浏览器发送选择的加密套件、service-random 和公钥;
- 浏览器保存公钥,并生成随机数 pre-master,然后利用公钥对 pre-master 加密,并向服务器发送加密后的数据;最后服务器拿出自己的私钥,解密出 pre-master 数据,并返回确认消息。
- 到此为止,服务器和浏览器就有了共同的 client-random、service-random 和 pre-master,然后服务器和浏览器会使用这三组随机数生成对称密钥,因为服务器和浏览器使用同一套方法来生成密钥,所以最终生成的密钥也是相同的。
pre-master是经过公钥加密之后传输的,所以黑客无法获取到pre-master,这样黑客就无法生成密钥,也就保证了黑客无法破解传输过程中的数据了。
通过对称和非对称混合方式,我们完美地实现了数据的加密传输。不过这种方式依然存在着问题,比如我要打开极客时间的官网,但是黑客通过 DNS 劫持将极客时间官网的 IP 地址替换成了黑客的 IP 地址,这样我访问的其实是黑客的服务器了,黑客就可以在自己的服务器上实现公钥和私钥,而对浏览器来说,它完全不知道现在访问的是个黑客的站点
添加数字证书
网站要证明这个服务器就是自己网站的,也需要使用权威机构颁发的证书,这个权威机构称为 CA(Certificate Authority),颁发的证书就称为数字证书(Digital Certificate)。
对于浏览器来说,数字证书有两个作用,一个是通过数字证书向浏览器证明服务器的身份,另一个是数字证书里面包含了服务器公钥。
通过引入数字证书,我们就实现了服务器的身份认证功能,这样即便黑客伪造了服务器,但是由于证书是没有办法伪造的,所以依然无法欺骗用户。
数字证书的申请和验证
如何申请数字证书
- 首先极客时间需要准备一套私钥和公钥,私钥留着自己使用;
- 然后极客时间向 CA 机构提交公钥、公司、站点等信息并等待认证,这个认证过程可能是收费的;CA 通过线上、线下等多种渠道来验证极客时间所提供信息的真实性,如公司是否存在、企业是否合法、域名是否归属该企业等;
- 如信息审核通过,CA 会向极客时间签发认证的数字证书,包含了极客时间的公钥、组织信息、CA 的信息、有效时间、证书序列号等,这些信息都是明文的,同时包含一个 CA 生成的签名。
首先 CA 使用 Hash 函数来计算极客时间提交的明文信息,并得出信息摘要;然后 CA 再使用它的私钥对信息摘要进行加密,加密后的密文就是 CA 颁给极客时间的数字签名。这就相当于房管局在房产证上盖的章,这个章是可以去验证的,同样我们也可以通过数字签名来验证是否是该 CA 颁发的。
浏览器如何验证数字证书
- 首先浏览器读取证书中相关的明文信息,采用 CA 签名时相同的 Hash 函数来计算并得到信息摘要 A
- 然后再利用对应 CA 的公钥解密签名数据,得到信息摘要 B
对比信息摘要 A 和信息摘要 B,如果一致,则可以确认证书是合法的,即证明了这个服务器是极客时间的
缓存
缓存概念与分类
数据库缓存
- 代理服务器缓存
- CDN缓存
-
浏览器缓存 按位置分
memory cache
- disk cache
Service Worker等
浏览器的资源缓存分为 from disk cache 和 from memory cache 两类
当首次访问网页时,资源文件被缓存在内存中,同时也会在本地磁盘中保留一份副本。
当用户刷新页面,如果缓存的资源没有过期,那么直接从内存中读取并加载。
当用关闭页面后,当前页面缓存在内存中的资源被清空。当用户再一次访问页面时,如果资源文件的缓存没有过期,那么将从本地磁盘进行加载,并再次缓存到内存之中
当你访问chrome中的url时,页面上的html和其他资产将本地存储在内存和磁盘缓存中。
chrome将首先使用内存缓存,因为它的速度快得多,但它也会将页面存储在磁盘缓存中,以防你退出浏览器或它崩溃,因为磁盘缓存是持久的。浏览器缓存按失效策略分 强制缓存 协商缓存
- 强制缓存 Expires Cache-control no-cache max-age no-store public private
2. 协商缓存 Etag Etag/If-None-Match Last-modified/If-Modified-Since If-None-Match 优先级更高HTTP2解决的问题
HTTP/2 的一个核心特性是使用了多路复用技术,因此它可以通过一个 TCP 连接来发送多个 URL 请求。多路复用技术能充分利用带宽,最大限度规避了 TCP 的慢启动所带来的问题,同时还实现了头部压缩、服务器推送等功能,使得页面资源的传输速度得到了大幅提升。
在 HTTP/1.1 时代,为了提升并行下载效率,浏览器为每个域名维护了 6 个 TCP 连接;而采用 HTTP/2 之后,浏览器只需要为每个域名维护 1 个 TCP 持久连接,同时还解决了 HTTP/1.1 队头阻塞的问题。TCP的队头阻塞
可以把 TCP 连接看成是两台计算机之前的一个虚拟管道,计算机的一端将要传输的数据按照顺序放入管道,最终数据会以相同的顺序出现在管道的另外一头。
正常情况
TCP 丢包
我们就把在 TCP 传输过程中,由于单个数据包的丢失而造成的阻塞称为 TCP 上的队头阻塞。
HTTP2.0多路复用
通过该图,我们知道在 HTTP/2 中,多个请求是跑在一个 TCP 管道中的,如果其中任意一路数据流中出现了丢包的情况,那么就会阻塞该 TCP 连接中的所有请求。这不同于 HTTP/1.1,使用 HTTP/1.1 时,浏览器为每个域名开启了 6 个 TCP 连接,如果其中的 1 个 TCP 连接发生了队头阻塞,那么其他的 5 个连接依然可以继续传输数据。
所以随着丢包率的增加,HTTP/2 的传输效率也会越来越差。有测试数据表明,当系统达到了 2% 的丢包率时,HTTP/1.1 的传输效率反而比 HTTP/2 表现得更好。