快速了解计算机网络 - 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请求次数,但还是客户端向服务端请求

相关推荐
牛奶9 分钟前
开发者的"奇技淫巧":那些让你效率翻倍的实战技巧
前端·后端·程序员
咸鱼翻身更入味9 分钟前
Vue创建一个简单的Agent聊天——工具调用
前端
Timo来了10 分钟前
indexDB的用法示例
前端
walking95713 分钟前
重新学习前端之设计模式与架构
前端·javascript·面试
walking95716 分钟前
重新学习前端之TypeScript
前端·javascript·面试
walking95716 分钟前
重新学习前端之Linux
前端·vue.js·面试
walking95717 分钟前
重新学习前端之CSS
前端·vue.js·面试
walking95717 分钟前
重新学习前端之Git
前端·vue.js·面试
walking95717 分钟前
重新学习前端之小程序
前端
魔术师Grace19 分钟前
AI让我退化成原始人了
前端·程序员