记一次 HTTP 的知识扫盲
What
什么是 HTTP ?
HTTP ( hypertext transfe protocol ) 超文本传输协议,是一个简单的 请求-响应 协议。
通过浏览器和服务的数据交互,进行超文本(文本、图片、视频等)传输数据的一种双向规定协。
Base
HTTP 通常运行在 TCP 之上,指定了客户端可能发送给服务器什么样的消息以及得到什么样的响应。
说到这里,就要提一句计算机网络的七层架构
- Level 1 物理层:网络的物理形式,例如平衡电缆、光纤、无线信道等;
- Level 2 数据链路层:用作网络的数据通道,建立逻辑连接、进行硬件地址寻址;
- Level 3 网络层:进行逻辑地址寻址,实现不同网络之间的路径选择,例 HTTP 协议;
- Level 4 传输层:进行网络数据通讯,TCP、UDP 协议,数据包离开网卡就会进入网络传输层;
- Level 5 会话层:建立和维会话同步;
- Level 6 表示层:把传输的数据转化合适的公共语言,以便交互操作,例如 JPEG、ASCll、DECOIC、加密格式;
- Level 7 应用层:面向具体的应用传输数据。
了解上述模型之后,知道 HTTP 的应用环境,在 TCP/IP 协议之上。
IP 在虚拟网络中,代替主机的真实物理 MAC 地址,作为地址;
TCP( Transmission Control Protocol ) 传输控制协议。是一种面向连接的、可靠的、基于字节流的传输层通信协议。TCP 会帮助我们建立链接,数据传输通道,会对数据进行分组和排序,可以保证数据不会丢失;
UDP ( User Datagram Protocol )用户数据报协议。与 TCP 协议一样,处于传输层,用于处理数据包。不过与 UDP 不提供数据包分组和排序,传输速度快,无法确定数据是否安全到达,数据有丢失的风险。
知道上述的概念后,数据的传输可以认为,每个主机(根据 IP 区分)发送数据,通过 TCP 建立的数据通道,使用 HTTP 协议传输到另一台主机上。它们依赖关系下图所示
至此,就可以开心的碎碎念记录 HTTP 了。
Content
HTTP 特点:超文本,灵活可扩展,可靠,请求-应答,无状态,明文。
Header
格式:请求行,请求头,空行,请求体
蓝色区域为请求行,后面为请求体,\r\n 空行(CRLF)表示请求体这一行的结束。
Hi,HTTP,我想搞点大数据还不能丢失,你能行吗。
数据分组
上述 HTTP 的一个特点是可灵活扩展,那么我们在传输大大大数据的时候,就可以使用数据分组的形式传输数据,浏览器会把分组的内容组装起来,用来保证数据可靠性。思路大致如下:
⚠️注意: 在分组传输大数据的时候,需要设置 TRansfer-Encoding: chunked
(不可与 content-length 同时使用)
Hi,HTTP,有个新活,看电影
范围请求
如果想在浏览器上看电影,按秒请求数据显然不合理,那么就需要设置请求的范围(偏移量),需要设置 Content-Type:bytes x-y/length
请求的响应数据也会有对应的状态标示,响应是否成功,206 - 数据存在;416 - 范围不存在。举个栗子🌰
请求:
GET
www.chrono.comRange: bytes=0-3
响应:
HTTP/1.1 206 Partial
ContentContent-Length:4
Accept-Ranges:bytesContent-Range:bytes=0-3/6
连接
说起 HTTP 的连接,就要提一提短链接和长连接。
短链接
就是我们请求一次就会有一次响应,就会建立 TCP 数据传输通道,任务结束,通道关闭。
长链接
发送请求,设置 Connection:keep-alive
就可以保持 TCP 通道在一段时间(手动设置 Connection:close
)内不会失效,可以发送和接受多个数据请求。
平常上网会遇见这样的问题,我上一次提交的东西,网络特别慢,还没告诉我结果,我又提交新东西,怎么页面好像卡住了,兄弟,那是因为对头阻塞了。
对头阻塞
“队头阻塞”与短连接和长连接无关,而是由 HTTP 基本的“请求 - 应答”模型所导致的。前一个堵住了,后面的需要一起等待。
解决:
- 1、并发连接。可以同时对一个域名发起多个长连接,用数量来解决质量的问题。但这种方式也存在缺陷。如果每个客户端都想自己快,建立很多个连接,用户数×并发数就会是个天文数字。服务器的资源根本就扛不住,或者被服务器认为是恶意攻击,反而会造成“拒绝服务”。所以,HTTP 协议建议客户端使用并发,但不能“滥用”并发;
- 2、域名分片。还是用数量来解决质量的思路。HTTP 协议和浏览器不是限制并发连接数量吗?好,那我就多开几个域名,比如 a.t.com、b.t.com,而这些域名都指向同一台服务器 www.t.com,这样实际长连接的数量就又上去了。
HTPPS
HTTPS ~= HTPP + Super
HTTPS 是以安全为目标的 HTTP 通道,在 HTTP 的基础上通过传输加密和身份认证保证了传输过程的安全性。
HTTPS 在 HTTP 的基础下加入 SSL,HTTPS 的加密安全基础是 SSL,可以理解为 S ~ SSL。
数据加密
HTTPS 采用的是 混合加密算法
,混合加密就是 对称加密
和 非对称加密
结合。
具体过程:
客户端发起请求 -> 服务器把公钥 A 明文传输给 客户端 -> 客户端随机生成一个对称加密的密钥 X,用公钥 A 加密后传给 服务器 -> 服务器用 私钥 A’ 进行解密拿到密钥 X -> 双方之后的数据传输用 X 加密解密;
身份验证
这样就完美了吗?不,还有纰漏。如果坏人劫持了公钥 A,并进行 “狸猫换太子”,把公钥 A 偷偷换成了自己的公钥 B,悄无声息的发送给客户端,不知情的客户端收到的公钥是被调包的公钥 B,那么之后的加密过程也是不安全的。
客户端怎么知道收到的公钥该不该信任呢?公钥A 怎么证明自己是真正的公钥呢?这时候就需要一个官方机构,给每个服务器发一个证书,就如同现实生活的公安局颁布的身份证一样,必要时可自证清白,双方都要无条件信任这个机构。这就出来了 CA 机构,颁发了 数字证书(身份证),使用 HTTPS 必须要无条件信任 CA ,无条件的产生信任链和数字证书链,实现身份认证和不可否认性。
HTTPS 在传输数据前会向 CA 申请 数字证书,证书里面含有 持有者信息和公钥 等信息。
那会不会数字证书被篡改呢?假设中间人篡改了证书的原文,由于他没有 CA 机构的私钥,所以无法得到此时加密后签名,无法相应地篡改签名。浏览器可以通过签名判断是否被篡改;
那会不会被调包呢?证书里包含了网站的信息,包括域名,浏览器把证书里的域名与自己请求的域名比对一下就知道有没有被掉包了。所以相对来说安全很多。
具体过程:
客户端发起 SSL 握手 -> 服务端将证书发送给客户端 -> 客户端检查是否为 CA (双方约定可信任证书签发机构)-> 服务端检查客户端 CA 证书 ;
HTTP 2
长江后浪推前浪,一节更比六节强。
HTTP 2 通过支持请求与响应的多路复用来减少延迟,通过压缩 HTTP 首部字段将协议开销降至最低,同时增加对请求优先级和服务器端推送的支持。
相对于 HTPP 1 升级版本做了如下的改动:
兼容 HTTP 1
二进制分帧
HTTP 2 中,同域名下所有通信都在单个连接上完成,该连接可以承载任意数量的双向数据流。每个数据流都以消息的形式发送,而消息又由一个或多个帧组成。多个帧之间可以乱序发送,根据帧首部的流标识可以重新组装。
- 多路复用
多路复用,代替原来的序列和阻塞机制。所有就是请求的都是通过一个 TCP连接并发完成。
同个域名只需要占用一个 TCP 连接,消除了因多个 TCP 连接而带来的延时和内存消耗。
单个连接上可以并行交错的请求和响应,之间互不干扰。
头部压缩
使用索引 + 哈夫曼编码,HTTP 2 在客户端和服务器端使用“首部表”来跟踪和存储之前发送的键值对,对于相同的数据,不再通过每次请求和响应发送。
服务器推送
服务端可以在发送页面HTML时主动推送其它资源,而不用等到浏览器解析到相应位置,发起请求再响应。例如服务端可以主动把JS和CSS文件推送给客户端,而不需要客户端解析HTML时再发送这些请求。
HTTP 3
强上加强,像不像毕设的绝不再改版。
先上图,看一眼,HTTP 3 的更改。传输层协议抛弃可靠稳定的 TCP ,采用 极快但可靠 的 UDP。
那数据丢失了怎么办?在UDP协议之上,新增了QUIC协议。
QUIC协议特性
- QUIC协议提供类似于HTTP2的流功能
- QUIC协议使用流ID取代IP和端口,这样就能实现连接迁移。例如说从4G信号切换到wifi,下层的IP和端口变了,但是由于QUIC的流ID没有变,这个连接不会变,可以继续使用这个连接。
懒人专享
HTTP、HTTP2 和 HTTP3 总结
这三者,都用TCP的握手协议去理解,都是握手,不同的是握手方式不一样。
- HTTPS 是类似于 TCP 握手的工作方式,先工作在 HTTP1 上,通过 HTTP1 传递交换得到秘钥,然后切换到 HTTPS 上工作;
- HTTP2也是基于 TLS 的,所以 HTTP 2 的工作方式和 HTTPS 也是同样的过程,需要握手建立 TLS 连接,只是 TLS 连接完成后,发送一个 HTTP2 的连接确认消息,确认后,客户端服务器使用HTTP2进行连接通讯。
- HTTP3 首先要建立好 HTTP 2 连接,然后发送 HTTP 2 扩展帧,这个帧包含IP和端口,浏览器收到扩展帧,使用该 IP 和端口,使用 QUIC 建立连接,如果成功,断开 HTTP2,升级为HTTP3。