「 面试三板斧 」之 HTTP (下)
今天的主要内容包括:
HTTP 是什么
HTTP 的前世今生
HTTP 的基础特性
基于 HTTP 的组件系统
HTTP 报文组成
HTTP 状态码
GET 和 Post的区别
优化 options 请求
HTTP/2 及 HTTP/3
HTTP 与 HTTPS 的区别
HTTPS 及其工作流程
为何不所有的网站都使用HTTPS ?
HTTP 2.0
2015年,HTTP2.0 面世。
HTTP/2 是二进制协议
而不是文本协议
。
相比于 HTTP/1,HTTP/2 可以说是大幅度提高了网页的性能
。
在 HTTP/1 中,为了性能考虑,我们会引入雪碧图、将小图内联、使用多个域名
等等的方式。
这一切都是因为浏览器限制了同一个域名下的请求数量
(Chrome 下一般是限制六个连接)。
当页面中需要请求很多资源
的时候,队头阻塞
(Head of line blocking)会导致在达到最大请求数量时,剩余的资源需要等待
其他资源请求完成后才能发起请求。
在 HTTP/2 中引入了多路复用的技术
,这个技术可以只通过一个 TCP 连接就可以传输所有的请求数据
。
多路复用
, 很好的解决了浏览器限制同一个域名下的请求数量的问题
,同时也间接更容易实现全速传输
,毕竟新开一个 TCP 连接都需要慢慢提升传输速度。
在线对比演示网站:https://http2.akamai.com/demo
看一下对比:
在深入原理之前,我们先来看几个概念:
帧
:客户端与服务器通过交换帧来通信,帧是基于这个新协议通信的最小单位。消息
:是指逻辑上的 HTTP 消息,比如请求、响应等,由一或多个帧组成。流
:流是连接中的一个虚拟信道,可以承载双向的消息;每个流都有一个唯一的整数标识符
HTTP 2.0 中的帧将 HTTP/1.x 消息分成帧
并嵌入到流 (stream) 中。
数据帧和报头帧分离,这将允许报头压缩
。
将多个流组合,这是一个被称为多路复用
(multiplexing) 的过程,它允许更有效的底层 TCP 连接。
也就是说,流
用来承载消息,消息又是有一个或多个帧组成。
二进制传输的方式更加提升了传输性能
。
每个数据流都以消息的形式发送,而消息又由一个或多个帧组成。
帧是流中的数据单位
。
HTTP 帧现在对 Web 开发人员是透明的。
在 HTTP/2 中,这是一个在 HTTP/1.1 和底层传输协议之间附加的步骤。
Web 开发人员不需要在其使用的 API 中做任何更改来利用 HTTP 帧;当浏览器和服务器都可用时,HTTP/2 将被打开并使用。
这是一个复用协议。
并行的请求能在同一个连接中处理,移除了 HTTP/1.x 中顺序和阻塞的约束。
多路复用允许同时通过单一的 HTTP/2 连接发起多重的请求-响应消息。
之前我们提到,虽然 HTTP 1.1 有了长连接和管道化的技术,但是还是会存在 队头阻塞。
而 HTTP 2.0 就解决了这个问题。
HTTP/2 中新的二进制分帧层突破了这些限制,实现了完整的请求和响应复用:
客户端和服务器可以将 HTTP 消息分解为互不依赖的帧,然后交错发送,最后再在另一端把它们重新组装起来。
如上图所示,快照捕捉了同一个连接内并行的多个数据流。
客户端正在向服务器传输一个 DATA 帧(数据流 5),与此同时,服务器正向客户端交错发送数据流 1 和数据流 3 的一系列帧。
因此,一个连接上同时有三个并行数据流。
将 HTTP 消息分解为独立的帧,交错发送,然后在另一端重新组装是 HTTP 2 最重要的一项增强。
事实上,这个机制会在整个网络技术栈中引发一系列连锁反应,从而带来巨大的性能提升,让我们可以:
并行交错地发送多个请求,请求之间互不影响。
并行交错地发送多个响应,响应之间互不干扰。
使用一个连接并行发送多个请求和响应。
消除不必要的延迟和提高现有网络容量的利用率,从而减少页面加载时间。
不必再为绕过 HTTP/1.x 限制而做很多工作(比如精灵图)
连接共享
即每一个 request 都是是用作连接共享机制的。
一个 request 对应一个 id,这样一个连接上可以有多个 request,每个连接的 request 可以随机的混杂在一起,接收方可以根据 request 的 id 将 request 再归属到各自不同的服务端请求里面。
加载一张大图,HTTP 1.1 和 HTTP 2.0 的对比:
HTTP 1.1 演示如下:
HTTP2.0 演示如下:
压缩了headers
HTTP1.x 的 header 带有大量信息,而且每次都要重复发送,就造成了性能的损耗。
为了减少此开销和提升性能,HTTP/2 使用 HPACK 压缩格式压缩请求和响应标头元数据.
这种格式采用两种简单但是强大的技术:
这种格式支持通过静态霍夫曼代码
对传输的标头字段进行编码,从而减小了各个传输的大小
。
这种格式要求客户端和服务器同时维护和更新一个包含之前见过的标头字段的索引列表。
换句话说,它可以建立一个共享的压缩上下文,此列表随后会用作参考,对之前传输的值进行有效编码。
服务端推送
其允许服务器在客户端缓存中填充数据,通过一个叫服务器推送的机制来提前请求。
服务器向客户端推送资源无需客户端明确地请求,服务端可以提前给客户端推送必要的资源,这样可以减少请求延迟时间,例如服务端可以主动把 JS 和 CSS 文件推送给客户端,而不是等到 HTML 解析到资源时发送请求,这样可以减少延迟时间大致过程如下图所示:
如何升级你的 HTTP 版本
使用 HTTP/1.1 和 HTTP/2 对于站点和应用来说是透明的。
拥有一个最新的服务器和新点的浏览器进行交互就足够了。
只有一小部分群体需要做出改变,而且随着陈旧的浏览器和服务器的更新,而不需 Web 开发者做什么,用的人自然就增加了。
HTTP/3
虽然 HTTP/2 解决了很多之前旧版本的问题,但是它还是存在一个巨大的问题,虽然这个问题并不是它本身造成的,而是底层支撑的 TCP 协议的问题
。
因为 HTTP/2 使用了多路复用,一般来说同一域名下只需要使用一个 TCP 连接。
当这个连接中出现了丢包的情况,那就会导致 HTTP/2 的表现情况反倒不如 HTTP/1 了。
因为在出现丢包的情况下,整个 TCP 都要开始等待重传,也就导致了后面的所有数据都被阻塞了。但是对于 HTTP/1 来说,可以开启多个 TCP 连接,出现这种情况反到只会影响其中一个连接,剩余的 TCP 连接还可以正常传输数据。
那么可能就会有人考虑到去修改 TCP 协议,其实这已经是一件不可能完成的任务了。因为 TCP 存在的时间实在太长,已经充斥在各种设备中,并且这个协议是由操作系统实现的,更新起来不大现实。
基于这个原因,Google 就更起炉灶搞了一个基于 UDP 协议的 QUIC 协议,并且使用在了 HTTP/3 上,当然 HTTP/3 之前名为 HTTP-over-QUIC,从这个名字中我们也可以发现,HTTP/3 最大的改造就是使用了 QUIC,接下来我们就来学习关于这个协议的内容。
QUIC
之前我们学习过 UDP
协议的内容,知道这个协议虽然效率很高
,但是并不是那么的可靠
。
QUIC 虽然基于 UDP,但是在原本的基础上新增了很多功能,比如多路复用、0-RTT、使用 TLS1.3 加密、流量控制、有序交付、重传等等功能。
这里我们就挑选几个重要的功能学习下这个协议的内容。
1.多路复用
虽然 HTTP/2 支持了多路复用,但是 TCP 协议终究是没有这个功能的。QUIC 原生就实现了这个功能,并且传输的单个数据流可以保证有序交付且不会影响其他的数据流,这样的技术就解决了之前 TCP 存在的问题。
并且 QUIC 在移动端的表现也会比 TCP 好。因为 TCP 是基于 IP 和端口去识别连接的,这种方式在多变的移动端网络环境下是很脆弱的。但是 QUIC 是通过 ID 的方式去识别一个连接,不管你网络环境如何变化,只要 ID 不变,就能迅速重连上。
2. 0-RTT
通过使用类似 TCP 快速打开的技术,缓存当前会话的上下文,在下次恢复会话的时候,只需要将之前的缓存传递给服务端验证通过就可以进行传输了。
3.纠错机制
假如说这次我要发送三个包,那么协议会算出这三个包的异或值并单独发出一个校验包,也就是总共发出了四个包。
当出现其中的非校验包丢包的情况时,可以通过另外三个包计算出丢失的数据包的内容。
当然这种技术只能使用在丢失一个包的情况下,如果出现丢失多个包就不能使用纠错机制了,只能使用重传的方式了。
HTTP 2/3 小结
HTTP/2 通过多路复用、二进制流、Header 压缩等等技术,极大地提高了性能,但是还是存在着问题的。
QUIC 基于 UDP 实现,是 HTTP/3 中的底层支撑协议,该协议基于 UDP,又取了 TCP 中的精华,实现了即快又可靠的协议。
HTTP 与 HTTPS 的区别
关于安全性,用最简单的比喻形容两者的关系就是卡车运货,HTTP下的运货车是敞篷的,货物都是暴露的。
而https则是封闭集装箱车,安全性自然提升不少。
HTTPS比HTTP更加安全,对搜索引擎更友好,利于SEO,谷歌、百度优先索引HTTPS网页; HTTPS需要用到SSL证书,而HTTP不用; HTTPS标准端口443,HTTP标准端口80; HTTPS基于传输层,HTTP基于应用层; HTTPS在浏览器显示绿色安全锁,HTTP没有显示;
HTTPS
HTTPS 也是通过 HTTP 协议进行传输信息,但是采用了 TLS
协议进行了加密。
在采用SSL后,HTTP 就拥有了 HTTPS 的加密
、证书
和完整性保护
这些功能。
也就是说HTTP加上加密处理和认证以及完整性保护后即是HTTPS。
HTTPS 协议的主要功能基本都依赖于 TLS/SSL 协议,TLS/SSL 的功能实现主要依赖于三类基本算法:
散列函数 对称加密 非对称加密,
其利用非对称加密
实现身份认证
和密钥协商
.
对称加密算法采用协商的密钥对数据加密,基于散列函数验证信息的完整性。
对称加密和非对称加密
对称加密就是两边拥有相同的秘钥,两边都知道如何将密文加密解密。
但是因为传输数据都是走的网络,如果将秘钥通过网络的方式传递的话,一旦秘钥被截获就没有加密的意义的.
非对称加密
公钥大家都知道,可以用公钥加密数据。
但解密数据必须使用私钥,私钥掌握在颁发公钥的一方。
首先服务端将公钥发布出去,那么客户端是知道公钥的。
然后客户端创建一个秘钥,并使用公钥加密,发送给服务端。
服务端接收到密文以后通过私钥解密出正确的秘钥
TLS 握手过程
TLS 握手的过程采用的是非对称加密
。
握手过程如下图所示:
Client Hello: 客户端发送一个随机值(Random1)以及需要的协议和加密方式。
Server Hello 以及 Certificate: 服务端收到客户端的随机值,自己也产生一个随机值(Random2),并根据客户端需求的协议和加密方式来使用对应的方式,并且发送自己的证书(如果需要验证客户端证书需要说明)
Certificate Verify: 客户端收到服务端的证书并验证是否有效,验证通过会再生成一个随机值(Random3),通过服务端证书的公钥去加密这个随机值并发送给服务端,如果服务端需要验证客户端证书的话会附带证书
Server 生成 secret: 服务端收到加密过的随机值并使用私钥解密获得第三个随机值(Random3),这时候两端都拥有了三个随机值,可以通过这三个随机值按照之前约定的加密方式生成密钥,接下来的通信就可以通过该密钥来加密解密。
HTTPS 工作流程
1.Client发起一个HTTPS(比如https://juejin.im/user/4283353031252967)的请求,根据RFC2818的规定,Client知道需要连接Server的443(默认)端口。
2.Server把事先配置好的公钥证书(public key certificate)返回给客户端。
3.Client验证公钥证书:比如是否在有效期内,证书的用途是不是匹配Client请求的站点,是不是在CRL吊销列表里面,它的上一级证书是否有效,这是一个递归的过程,直到验证到根证书(操作系统内置的Root证书或者Client内置的Root证书)。如果验证通过则继续,不通过则显示警告信息。
4.Client使用伪随机数生成器生成加密所使用的对称密钥,然后用证书的公钥加密这个对称密钥,发给Server。
5.Server使用自己的私钥(private key)解密这个消息,得到对称密钥。至此,Client和Server双方都持有了相同的对称密钥。
6.Server使用对称密钥加密“明文内容A”,发送给Client。
7.Client使用对称密钥解密响应的密文,得到“明文内容A”。
8.Client再次发起HTTPS的请求,使用对称密钥加密请求的“明文内容B”,然后Server使用对称密钥解密密文,得到“明文内容B”。
为何不所有的网站都使用HTTPS
既然HTTPS那么安全可靠,那为何不所有的Web网站都使用HTTPS?
首先,很多人还是会觉得HTTPS实施有门槛,这个门槛在于需要权威CA颁发的SSL证书。从证书的选择、购买到部署,传统的模式下都会比较耗时耗力。
其次,HTTPS普遍认为性能消耗要大于HTTP,因为与纯文本通信相比,加密通信会消耗更多的CPU及内存资源。如果每次通信都加密,会消耗相当多的资源,平摊到一台计算机上时,能够处理的请求数量必定也会随之减少。
但事实并非如此,用户可以通过性能优化、把证书部署在SLB或CDN,来解决此问题。
举个实际的例子,“双十一”期间,全站HTTPS的淘宝、天猫依然保证了网站和移动端的访问、浏览、交易等操作的顺畅、平滑。
通过测试发现,经过优化后的许多页面性能与HTTP持平甚至还有小幅提升,因此HTTPS经过优化之后其实并不慢。
除此之外,想要节约购买证书的开销也是原因之一。
要进行HTTPS通信,证书是必不可少的。而使用的证书必须向认证机构(CA)购买。
最后是安全意识。
相比国内,国外互联网行业的安全意识和技术应用相对成熟,HTTPS部署趋势是由社会、企业、政府共同去推动的。
(参考链接:https://juejin.cn/post/6844903830987997197)
爱心三连击
1.看到这里了就点个在看支持下吧,你的在看是我创作的动力。
2.关注公众号脑洞前端,获取更多前端硬核文章!加个星标,不错过每一条成长的机会。
3.如果你觉得本文的内容对你有帮助,就帮我转发一下吧。