图解 HTTP 协议

提示:文章结合图片,介绍 HTTP 协议相关知识。


一、知识概览

以下是 HTTP 常见的五大类问题:

示例图片

本文将对上述知识点进行逐一介绍。

二、基础知识

HTTP 是超文本传输协议,也就是 HyperText Transfer Protocol。如图所示:

示例图片

HTTP 使用计算机能够理解的语言确立了一种计算机之间交流通信的规范(两个以上的参与者),以及相关的各种控制和错误处理方式(行为约定和规范),是一个双向协议。协议传输的内容是“超文本”,超文本就是超越了普通文本的文本,它是文字、图片、视频等的混合体,最关键有超链接,能从一个超文本跳转到另外一个超文本(HTML 就是最常见的超文本)。

以下是 HTTP 的五大类状态码:

示例图片

来看下 HTTP 的几个常见的字段。Host 字段用来(客户端发送请求时)指定服务器的域名,有了 Host 字段,就可以将请求发往同一台服务器上的不同网站:

示例图片

Content-Length 字段表明服务器本次回应的数据长度:

示例图片

Connection 字段最常用于客户端要求服务器使用 TCP 持久连接,以便其他请求复用。HTTP/1.1 版本的默认连接都是持久连接,但为了兼容老版本的 HTTP,需要指定 Connection 首部字段的值为 Keep-Alive:

示例图片

Content-Type 字段用于服务器回应时,告诉客户端,本次数据是什么格式:

示例图片

Content-Encoding 字段说明数据的压缩方法,表示服务器返回的数据使用了什么压缩格式:

示例图片

三、GET 与 POST

Get 方法的含义是请求从服务器获取资源,这个资源可以是静态的文本、页面、图片视频等。

示例图片

而 POST 方法则是相反操作,它向 URI 指定的资源提交数据,数据就放在报文的 body 里。

示例图片

来看两个概念,安全和幂等:

  • 在 HTTP 协议里,所谓的“安全”是指请求方法不会“破坏”服务器上的资源。
  • 所谓的“幂等”,意思是多次执行相同的操作,结果都是“相同”的。

所以 GET 方法是安全且幂等的,因为它是只读操作。POST 不是安全的,也不是幂等的,因为它会“新增或提交数据”。

四、HTTP 特性

HTTP 最凸出的优点是简单、灵活和易于扩展、应用广泛和跨平台。HTTP 由于是工作在应用层(OSI 第七层),它下层可以随意变化。HTTP 协议是无状态的,服务器不会去记忆 HTTP 的状态,这能减轻服务器的负担。但无状态也有坏处,在完成有关联性的操作时会非常麻烦,每请求一次都要问一遍身份信息。可以用 Cookie 技术来解决无状态的问题,相当于在客户端第一次请求后,服务器会下发一个装有客户信息的“小贴纸”,后续客户端请求服务器的时候,带上“小贴纸”,服务器就能认得了。

示例图片

那么,HTTP/1.1 的性能如何?早期 HTTP/1.0 每发起一个请求,都要新建一次 TCP 连接(三次握手)。HTTP/1.1 提出了长连接的通信方式,也叫持久连接,只要任意一端没有明确提出断开连接,则保持 TCP 连接状态,减少了重复建立和断开链接的额外开销。

HTTP/1.1 采用了长连接的方式,这使得管道(pipeline)网络传输成为了可能。即可在同一个 TCP 连接里面,客户端可以发起多个请求,只要第一个请求发出去了,不必等其回来,就可以发第二个请求出去,可以减少整体的响应时间。服务器按照顺序,先回应第一个请求,完成后再回应第二个请求。服务器回应的时候,要是前面的回应特别慢,后面就会有许多请求排队等着,这称为“队头堵塞”。

总之 HTTP/1.1 的性能一般,后续的 HTTP/2 和 HTTP/3 就是在优化 HTTP 的性能。

五、HTTP 与 HTTPS

HTTP 是超文本传输协议,信息是明文传输,存在安全风险的问题。HTTPS 在 TCP 和 HTTP 网络层之间加入了 SSL/TLS 安全协议,使得报文能够加密传输。HTTP 连接建立相对简单, TCP 三次握手之后便可进行 HTTP 的报文传输。而 HTTPS 在 TCP 三次握手之后,还需进行 SSL/TLS 的握手过程,才可进入加密报文传输。

TLS 和 SSL 实际上是一个东西。SSL 是洋文 “Secure Sockets Layer 的缩写,中文叫做安全套接层。它是在上世纪 90 年代中期,由网景公司设计的。到了1999年,SSL 因为应用广泛,已经成为互联网上的事实标准。IETF 就在那年把 SSL 标准化。标准化之后的名称改为 TLS(Transport Layer Security”),中文叫做传输层安全协议。很多相关的文章都把这两者并列称呼(SSL/TLS),因为这两者可以视作同一个东西的不同阶段。

示例图片

HTTPS 是这样解决风险的:
① 通过混合加密(对称加密和非对称加密结合)的方式可以保证信息的机密性,解决了窃听的风险。在通信建立前采用非对称加密的方式交换“会话秘钥”,后续就不再使用非对称加密;在通信过程中全部使用对称加密的“会话秘钥”的方式加密明文数据。

示例图片

② 摘要算法用来实现完整性,能够为数据生成独一无二的“指纹”,用于校验数据的完整性,解决了篡改的风险。客户端在发送明文之前会通过摘要算法算出明文的“指纹”,发送的时候把“指纹 + 明文”一同加密成密文后,发送给服务器,服务器解密后,用相同的摘要算法算出发送过来的明文,通过比较客户端携带的“指纹”和当前算出的“指纹”做比较,若“指纹”相同,说明数据是完整的。

示例图片

③ 数字证书。客户端先向服务器端索要公钥,然后用公钥加密信息,服务器收到密文后,用自己的私钥解密。这就存在些问题,如何保证公钥不被篡改和信任度?所以这里就需要借助第三方权威机构 CA (数字证书认证机构),将服务器公钥放在数字证书(由数字证书认证机构颁发)中,只要证书是可信的,公钥就是可信的。

示例图片

SSL/TLS 协议建立的详细流程:
① 首先,由客户端向服务器发起加密通信请求,也就是 ClientHello 请求。客户端主要向服务器发送以下信息:客户端支持的 SSL/TLS 协议版本,如 TLS 1.2 版本;客户端生产的随机数(Client Random),后面用于生产“会话秘钥”;客户端支持的密码套件列表,如 RSA 加密算法。
② 服务器收到客户端请求后,向客户端发出响应,也就是 SeverHello 。服务器回应的内容有如下内容:确认 SSL/ TLS 协议版本,如果浏览器不支持,则关闭加密通信;服务器生产的随机数(Server Random),后面用于生产“会话秘钥”;确认的密码套件列表,如 RSA 加密算法;服务器的数字证书。
③ 客户端收到服务器的回应之后,首先通过浏览器或者操作系统中的 CA 公钥,确认服务器的数字证书的真实性。如果证书没有问题,客户端会从数字证书中取出服务器的公钥,然后使用它加密报文,向服务器发送如下信息:一个随机数(pre-master key),该随机数会被服务器公钥加密,这里的随机数是整个握手阶段的第三个随机数,这样服务器和客户端就同时有三个随机数,接着就用双方协商的加密算法,各自生成本次通信的“会话秘钥”;加密通信算法改变通知,表示随后的信息都将用“会话秘钥”加密通信;客户端握手结束通知,表示客户端的握手阶段已经结束,这一项同时把之前所有内容的发生的数据做个摘要,用来供服务端校验。
④ 服务器收到客户端的第三个随机数(pre-master key)之后,通过协商的加密算法,计算出本次通信的“会话秘钥”。然后,向客户端发送最后的信息:加密通信算法改变通知,表示随后的信息都将用“会话秘钥”加密通信;服务器握手结束通知,表示服务器的握手阶段已经结束,这一项同时把之前所有内容的发生的数据做个摘要,用来供客户端校验。

示例图片

SSL/TLS 1.2 需要 4 次握手,需要 2 个 RTT 的时延,文中的图是把每个交互分开画了,实际上把他们合在一起发送,就是 4 次握手:

示例图片

另外, SSL/TLS 1.3 优化了过程,只需要 1 个 RTT 往返时延,也就是只需要 3 次握手:

示例图片

至此,整个 SSL/TLS 的握手阶段全部结束。接下来,客户端与服务器进入加密通信,就完全是使用普通的 HTTP 协议,只不过用“会话秘钥”加密内容。

六、HTTP/1.1、HTTP/2、HTTP/3 演变

HTTP/1.1 相比 HTTP/1.0 性能上的改进:
① 使用 TCP 长连接的方式改善了 HTTP/1.0 短连接造成的性能开销;
② 支持管道(pipeline)网络传输,只要第一个请求发出去了,不必等其回来,就可以发第二个请求出去,可以减少整体的响应时间。

但 HTTP/1.1 还是有性能瓶颈:
① 只能压缩 Body 的部分,请求 / 响应头部(Header)未经压缩就发送,首部信息越多延迟越大,每次互相发送相同的首部造成的浪费较多;
② 服务器是按请求的顺序响应的,如果服务器响应慢,会招致客户端一直请求不到数据,也就是队头阻塞;
③ 没有请求优先级控制;
④ 请求只能从客户端开始,服务器只能被动响应。

HTTP/2 相比 HTTP/1.1 性能上的改进:
① HTTP/2 会压缩头(Header),如果同时发出多个请求,他们的头是一样的或是相似的,那么协议会消除重复的部分。这就是所谓的 HPACK 算法,即在客户端和服务器同时维护一张头信息表,所有字段都会存入这个表,生成一个索引号,以后就不发送同样字段了,只发送索引号,这样就提高速度了。
② HTTP/2 不再像 HTTP/1.1 里的纯文本形式的报文,而是全面采用了二进制格式,头信息和数据体都是二进制,并且统称为帧(头信息帧和数据帧)。计算机只懂二进制,这样收到报文后无需再将明文转成二进制,而是直接解析二进制报文,增加了数据传输的效率。

示例图片

③ HTTP/2 的数据包不是按顺序发送的,同一个连接里面连续的数据包,可能属于不同的回应。因此,必须要对数据包做标记,指出它属于哪个回应。每个请求或回应的所有数据包,称为一个数据流(Stream)。每个数据流都标记着一个独一无二的编号,其中规定客户端发出的数据流编号为奇数, 服务器发出的数据流编号为偶数客户端还可以指定数据流的优先级。优先级高的请求,服务器就先响应该请求。

示例图片

④ HTTP/2 是可以在一个连接中并发多个请求或回应,而不用按照顺序一一对应。移除了 HTTP/1.1 中的串行请求,不需要排队等待,也就不会再出现队头阻塞问题,降低了延迟,大幅度提高了连接的利用率。举例来说,在一个 TCP 连接里,服务器收到了客户端 A 和 B 的两个请求,如果发现 A 处理过程非常耗时,于是就回应 A 请求已经处理好的部分,接着回应 B 请求,完成后,再回应 A 请求剩下的部分。

示例图片

⑤ HTTP/2 服务器不再是被动地响应,也可以主动向客户端发送消息。举例来说,在浏览器刚请求 HTML 的时候,就提前把可能会用到的 JS、CSS 文件等静态资源主动发给客户端,减少延时的等待,也就是服务器推送(Server Push,也叫 Cache Push)。

HTTP/2 主要的问题在于,多个 HTTP 请求在复用一个 TCP 连接,下层的 TCP 协议是不知道有多少个HTTP 请求的。所以一旦发生了丢包现象,就会触发 TCP 的重传机制,这样在一个 TCP 连接中的所有的 HTTP 请求都必须等待这个丢了的包被重传回来。而 HTTP/1.1 中的管道传输中如果有一个请求阻塞了,那么队列后请求也统统被阻塞住了。这都是基于 TCP 传输层的问题,所以 HTTP/3 把 HTTP 下层的 TCP 协议改成了 UDP。

示例图片

UDP 是不可靠传输的,但基于 UDP 的 QUIC 协议可以实现类似 TCP 的可靠性传输。QUIC 有自己的一套机制可以保证传输的可靠性的。当某个流发生丢包时,只会阻塞这个流,其他流不会受到影响。TLS3 升级成了最新的 1.3 版本,头部压缩算法也升级成了 QPack 。HTTPS 要建立一个连接,要花费 6 次交互,先是建立三次握手,然后是 TLS/1.3 的三次握手,QUIC 直接把以往的 TCP 和 TLS/1.3 的 6 次交互合并成了 3 次,减少了交互次数。

示例图片

所以, QUIC 是一个在 UDP 之上的伪 TCP + TLS + HTTP/2 的多路复用的协议。QUIC 是新协议,对于很多网络设备,根本不知道什么是 QUIC,只会当做 UDP,这样会出现新的问题。所以 HTTP/3 现在普及的进度非常的缓慢,不知道未来 UDP 是否能够逆袭 TCP。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值