快速了解计算机网络 - HTTP篇

TCP/IP 原理体系结构

  • 应用层:解决通过应用进程的交互 来实现特定网络应用的问题
  • 运输层(传输层):解决进程 之间基于网络通信的问题
  • 网络层:解决分组在多个网络上传输(路由)的问题
  • 数据链路层:解决分组在一个网络或一段链路上传输的问题
  • 物理层:解决用何种信号传输比特的问题

输入浏览器地址到首页渲染经历了什么

  1. URL 进行解析,从而生成发送给 Web 服务器的请求信息。
  2. 主机的DNS客户端进程DNS服务器 发生DNS查询请求报文,问该域名对应的ip地址是多少
  3. DNS查询请求报文 使用运输层的UDP协议封装,目的端口号设置成53
  4. DNS服务器 收到该请求报文,因为目的端口号为53,将其交给DNS服务器端进程
  5. DNS服务器端进程 查找对应的ip地址,然后发送DNS响应报文,告诉该域名对应的ip地址
  6. 主机的DNS客户端进程收到该数据报并解析后,就知道对应的ip地址了
  7. 然后准备发送 HTTP请求报文,经历 TCP 三次握手
  8. 第一次握手:客户端发送 SYN = 1, 序列号初始化为一个随机数的消息
  9. 第二次握手:服务端发送 SYN = 1, ACK = 1, 确认应答号初始化为客户端随机数 + 1, 序列号为服务端随机数的消息
  10. 第三次握手:客户端发送 ACK = 1, 确认应答号为服务端随机数 + 1的消息
  11. 然后主机的HTTP客户端进程 向web服务器发送HTTP请求报文,问首页的内容是什么
  12. HTTP请求报文 通过TCP协议封装,目的端口号为80
  13. web服务器的HTTP服务器端进程 收到该请求报文,返回HTTP响应报文,里面包含首页内容
  14. 处理 HTML 标记并构建 DOM 树
  15. 处理 CSS 标记并构建 CSSOM 树
  16. 将 DOM 与 CSSOM 合并成一个渲染树
  17. 根据渲染树来布局,以计算每个节点的几何信息
  18. 将各个节点绘制到屏幕上。

域名系统DNS

例:www.baidu.com

  • 每级域名用.隔开,级别低的域名在左边,级别高的在右边

域名服务器四种类型

  • 根域名服务器 :最高层次的域名服务器。共有13个(每个实际是服务器集群),每个根域名服务器知道所有的顶级域名服务器 的域名及其ip地址。根域名服务器通常不直接解析域名 而是返回该域名所属顶级域名服务器的IP地址
  • 顶级域名服务器 :负责管理在该服务器注册的所有二级域名 ,收到DNS查询请求时给出相应的回答(可能是最后结果,也可能是下一级权限域名服务器的IP地址
  • 权限域名服务器管理某个区的域名,每一个主机的域名都必须在某个权限域名服务器中登记
  • 本地域名服务器 :不属于上述域名服务器的登记结构,本地域名服务器起着代理的作用,会把DNS请求报文转发到上述域名服务器的等级结构中

域名解析的过程

  1. 主机向本地域名服务器 进行递归查询
  2. 本地域名服务器根域名服务器 进行迭代查询
  3. 根域名服务器 告诉本地域名服务器 下一次应查询的顶级域名服务器的IP地址
  4. 本地域名服务器顶级域名服务器 进行迭代查询
  5. 顶级域名服务器 告诉本地域名服务器 下一次应查询的权限域名服务器的IP地址
  6. 本地域名服务器权限域名服务器 进行迭代查询
  7. 权限域名服务器 告诉本地域名服务器所查询域名的IP地址
  8. 本地域名服务器告诉主机所查询域名的IP地址

HTTP

HTTP/1.0

  • 采用短连接,每次浏览器请求一个文件都要建立TCP连接,收到响应后立即关闭连接

HTTP/1.1

  • 使用长连接,建立连接后不会立即关闭,等到通信双方其中一方主动提出关闭才关闭
  • 支持管道网络传输,只要第一个请求发出去了,不必等其回来,就可以发送第二个请求

缺点(5):

  • 请求 / 响应头部(header)未经压缩就发送,首部信息越多延迟越大
  • 发送冗长的首部。每次互相发送相同的首部造成的浪费较多
  • 仍然存在服务器队头阻塞,如果服务器响应慢,会招致客户端一直请求不到数据
  • 没有请求优先级控制
  • 请求只能从客户端开始,服务器只能被动响应

HTTP/2

HTTP/2 协议是 基于 HTTPS 的,所以 HTTP/2 的安全性也是有保障的

  • 头部压缩 :如果你同时发出多个请求,他们的头是一样的或是相似的,那么,协议会帮你消除重复的部分
  • 二进制格式 :收到报文后,无需再将明文的报文转成二进制,而是直接解析二进制报文,这增加了数据传输的效率
  • 并发传输 :出了 Stream 概念,多个 Stream 复用在一条 TCP 连接,Stream 里可以包含 1 个或多个 Message,Message 对应 HTTP/1 中的请求或响应 ,由 HTTP 头部和包体构成。Message 里包含一条或者多个 Frame,FrameHTTP/2 最小单位 ,以二进制压缩格式存放 HTTP/1 中的内容(头部和包体)。针对不同的 HTTP 请求用独一无二的 Stream ID 来区
  • 服务器推送 :服务端不再是被动地响应,可以主动 向客户端发送消息。客户端和服务器双方都可以建立 Stream, Stream ID 也是有区别的,客户端建立的 Stream 必须是奇数号,而服务器建立的 Stream 必须是偶数号。

缺点:

  • TCP层队头阻塞 :TCP 层必须保证收到的字节数据是完整且连续 的,这样内核才会将缓冲区里的数据返回给 HTTP 应用,那么当「前 1 个字节数据」没有到达时,后收到的字节数据只能存放在内核缓冲区里,一旦发生了丢包现象,就会触发 TCP 的重传机制,这样在一个 TCP 连接中的所有的 HTTP 请求都必须等待这个丢了的包被重传回来

HTTP/3

HTTP/3 把 HTTP 下层的 TCP 协议改成了 UDP ,基于 UDP 的 QUIC 协议 可以实现类似 TCP 的可靠性传输

  • 无队头阻塞当某个流发生丢包时,只会阻塞这个流,其他流不会受到影响,因此不存在队头阻塞问题。这与 HTTP/2 不同,HTTP/2 只要某个流中的数据包丢失了,其他流也会因此受影响。
  • 更快的连接建立QUIC 内部包含了 TLS,它在自己的帧会携带 TLS 里的"记录",再加上 QUIC 使用的是 TLS/1.3,因此仅需 1 个 RTT 就可以「同时」完成建立连接与密钥协商
  • 连接迁移 :基于 TCP 传输协议的 HTTP 协议,由于是通过四元组(源 IP、源端口、目的 IP、目的端口)确定一条 TCP 连接。QUIC 协议没有用四元组的方式来"绑定"连接,而是通过连接 ID 来标记通信的两个端点,客户端和服务器可以各自选择一组 ID 来标记自己,因此即使移动设备的网络变化后,导致 IP 地址变化了,只要仍保有上下文信息(比如连接 ID、TLS 密钥等),就可以"无缝"地复用原连接,消除重连的成本,没有丝毫卡顿感,达到了连接迁移的功能。

HTTP 缓存

  • 强制缓存 :浏览器决定是否使用缓存
    • Cache-Cotrol: 响应字段,一个相对时间,由请求资源的时间和过期时间决定,优先级高
    • Expires: 响应字段,一个绝对时间,优先级低
  • 协商缓存 :与服务器协商是否使用缓存
    • 第一组:请求头:If-Modified-Since保存上一次的最后修改时间,响应头:Last-Modified响应资源最后修改时间,优先级低
    • 第二组:请求头:If-None-Match保存上一个唯一标识,响应头:ETag唯一标识响应资源,优先级高

HTTPS

HTTPS 在 HTTP 与 TCP 层之间加入了 SSL/TLS 协议

HTTPS 解决了 HTTP 的哪些问题?

  • 通过混合加密 保证了信息的机密性
  • 通过摘要算法计算出内容的哈希值 保证了信息的完整性
  • 通过将服务器公钥放入到数字证书中,保证了信息不会被冒充。

混合加密

HTTPS 采用的是对称加密非对称加密结合的「混合加密」方式

非对称加密 采用私钥加密,公钥解密 保证消息不会被冒充

加密是对内容的哈希值进行加密

HTTPS 是如何建立连接的?

SSL/TLS 协议基本流程:

  • 客户端向服务器索要并验证服务器的公钥。
  • 双方协商生产「会话秘钥」。
  • 双方采用「会话秘钥」进行加密通信。

RSA 加密流程

  1. 客户端发起加密请求:Client Hello::发送客户端支持的 TLS 协议版本客户端生产的随机数客户端支持的密码套件列表(3)
  2. 服务端返回响应:Server Hello::发送确认 TLS 协议版本 ,如果浏览器不支持,则关闭加密通信、服务器生产的随机数确认的密码套件列表 、Server Certificate::服务器的数字证书Server Hello Done:: 表示打招呼完毕(4)
  3. 客户端通过CA 公钥确认服务器的数字证书的真实性 ,没有问题,从数字证书中取出服务器的公钥 ,然后使用它加密报文,向服务器发送信息:Client Key Exchange::一个随机数 ,会被服务器公钥加密、Change Cipher Spec::加密通信算法改变通知 ,表示随后的信息都将用「会话秘钥」加密通信、Encrypted Handshake Message(Finishd)::客户端握手结束通知同时把之前所有内容的发生的数据做个摘要,用来供服务端校验。(3)
  4. 服务器收到客户端的第三个随机数之后,通过协商的加密算法,计算出本次通信的「会话秘钥」 ,向客户端发送最后的信息:Change Cipher Spec::加密通信算法改变通知 ,表示随后的信息都将用「会话秘钥」加密通信、Encrypted Handshake Message::服务器握手结束通知同时把之前所有内容的发生的数据做个摘要,用来供客户端校验。(2)

使用 RSA 密钥协商算法的最大问题是不支持前向保密: 一旦服务端的私钥泄漏了,过去被第三方截获的所有 TLS 通讯密文都会被破解。

CA 签发证书的过程,如上图左边部分:

  • 首先 CA 会把持有者的公钥、用途、颁发者、有效时间等信息打成一个包,然后对这些信息进行 Hash 计算,得到一个 Hash 值;
  • 然后 CA 会使用自己的私钥将该 Hash 值加密,生成 Certificate Signature,也就是 CA 对证书做了签名;
  • 最后将 Certificate Signature 添加在文件证书上,形成数字证书;

客户端校验服务端的数字证书的过程,如上图右边部分:

  • 首先客户端会使用同样的 Hash 算法获取该证书的 Hash 值 H1;
  • 通常浏览器和操作系统中集成了 CA 的公钥信息,浏览器收到证书后可以使用 CA 的公钥解密 Certificate Signature 内容,得到一个 Hash 值 H2 ;
  • 最后比较 H1 和 H2,如果值相同,则为可信赖的证书,否则则认为证书不可信。

ECDHE 加密流程

  1. 客户端发送消息:Client Hello::客户端使用的 TLS 版本号支持的密码套件列表 ,以及生成的随机数
  2. 服务端返回:Server Hello::确认的 TLS 版本号一个随机数确认的密码套件 ,然后Certificate::发送数字证书 ,Server Key Exchange发送选择的椭圆曲线生成随机数作为椭圆曲线的私钥保存本地 ,根据椭圆曲线基点 G 和私钥计算出服务端椭圆曲线公钥,Server Hello Done::打招呼完毕
  3. 客户端校验证书,如果没问题,生成一个随机数作为客户端椭圆曲线的私钥,发送消息:Client Key Exchange::客户端生成的椭圆曲线公钥 ,Change Cipher Spec::最终的会话密钥,就是用「客户端随机数 + 服务端随机数 + x(ECDHE 算法算出的共享密钥) 」三个材料生成的,告诉服务端后续改用对称算法加密通信,Encrypted Handshake Message::之前发送的数据做一个摘要,再用对称密钥加密一下,让服务端做个验证。
  4. 服务端发送:Client Key Exchange::服务端生成的椭圆曲线公钥,Encrypted Handshake Message::之前发送的数据做一个摘要,再用对称密钥加密一下,让客户端做个验证

两者区别:

  • RSA 密钥协商算法「不支持」前向保密,ECDHE 密钥协商算法「支持」前向保密;
  • 使用了 RSA 密钥协商算法,TLS 完成四次握手后,才能进行应用数据传输,而对于 ECDHE 算法,客户端可以不用等服务端的最后一次 TLS 握手,就可以提前发出加密的 HTTP 数据,节省了一个消息的往返时间(这个是 RFC 文档规定的,具体原因文档没有说明,所以这点我也不太明白);
  • 使用 ECDHE, 在 TLS 第 2 次握手中,会出现服务器端发出的「Server Key Exchange」消息,而 RSA 握手过程没有该消息;

WebSocket

WebSocket是基于TCP的新协议

建立WebSocket连接

浏览器在 TCP 三次握手 建立连接之后,统一使用 HTTP 协议先进行一次通信。

  • 如果这时候是想建立 WebSocket 连接 ,就会在 HTTP 请求里带上一些特殊的header 头 ,包含一段随机生成的 base64 码
makefile 复制代码
Connection: Upgrade
Upgrade: WebSocket
Sec-WebSocket-Key: T2a6wZlAwhgQNqruZ2YUyg==\r\n
  • 服务器正好支持升级成 WebSocket 协议,根据客户端生成的 base64 码,用某个公开的 算法变成另一段字符串,放在 HTTP 响应的 Sec-WebSocket-Accept 头里,同时带上101状态码,发回给浏览器,浏览器也用同样的公开算法base64码转成另一段字符串,如果这段字符串跟服务器传回来的字符串一致,那验证通过。

一来一回两次 HTTP 握手,WebSocket就建立完成了,后续双方就可以使用 websocket 的数据格式进行通信了。

长轮询

发起一个请求,在较长时间内等待服务器响应的机制,就是所谓的长轮询机制 ,相比于一般轮询可以减少HTTP请求次数,但还是客户端向服务端请求

相关推荐
轻口味几秒前
【每日学点鸿蒙知识】AVCodec、SmartPerf工具、web组件加载、监听键盘的显示隐藏、Asset Store Kit
前端·华为·harmonyos
alikami3 分钟前
【若依】用 post 请求传 json 格式的数据下载文件
前端·javascript·json
吃杠碰小鸡37 分钟前
lodash常用函数
前端·javascript
emoji1111111 小时前
前端对页面数据进行缓存
开发语言·前端·javascript
泰伦闲鱼1 小时前
nestjs:GET REQUEST 缓存问题
服务器·前端·缓存·node.js·nestjs
m0_748250031 小时前
Web 第一次作业 初探html 使用VSCode工具开发
前端·html
一个处女座的程序猿O(∩_∩)O1 小时前
vue3 如何使用 mounted
前端·javascript·vue.js
m0_748235951 小时前
web复习(三)
前端
AiFlutter1 小时前
Flutter-底部分享弹窗(showModalBottomSheet)
java·前端·flutter
麦兜*1 小时前
轮播图带详情插件、uniApp插件
前端·javascript·uni-app·vue