零、究极省流版

  1. 浏览器根据请求的 URL 交给 DNS 域名解析,找到真实 IP ,向服务器发起请求;
  2. 服务器交给后台处理完成后返回数据,浏览器接收文件( HTML、JS、CSS 、图像等);
  3. 浏览器对加载到的资源( HTML、JS、CSS 等)进行语法解析,建立相应的内部数据结构 (如 HTML 的 DOM);
  4. 载⼊解析到的资源文件,渲染页面,完成。

一、HTTP

1.1 解析URL

URL 解析

浏览器查看缓存,如果请求资源在缓存中并且新鲜,跳转到转码步骤;如果资源未缓存,发起新请求

检验新鲜通常有两个HTTP头进行控制 Expires 和 Cache-Control:

  • HTTP1.0提供 Expires,值为⼀个绝对时间表示缓存新鲜⽇期
  • HTTP1.1增加了Cache-Control: max-age=time,值为以秒为单位的最⼤新鲜时间

1.2 生成HTTP请求消息(HTTP报文)

HTTP 的消息格式

二、DNS

通过浏览器解析 URL 并生成 HTTP 消息后,需要委托操作系统将消息发送给 Web 服务器。

但在发送之前,还有一项工作需要完成,那就是查询服务器域名对应的 IP 地址,因为委托操作系统发送消息时,必须提供通信对象的 IP 地址。

2.1 域名解析的工作流程(递归查询)

  1. 客户端首先会发出一个 DNS 请求,问www.server.com的 IP 是啥,并发给本地 DNS 服务器(也就是客户端的 TCP/IP 设置中填写的 DNS 服务器地址)。(浏览器会先看自身有没有对这个域名的缓存,如果有,就直接返回,如果没有,就去问操作系统,操作系统也会去看自己的缓存,如果有,就直接返回,如果没有,再去 hosts 文件看,也没有,才会去问「本地 DNS 服务器」。)
  2. 本地域名服务器收到客户端的请求后,如果缓存里的表格能找到 www.server.com,则它直接返回 IP 地址。如果没有,本地 DNS 会去问它的根域名服务器。
  3. 根 DNS 收到来自本地 DNS 的请求后,发现后置是 .com,说:“www.server.com 这个域名归 .com 区域管理”,我给你 .com 顶级域名服务器地址给你,你去问问它吧。”
  4. 本地 DNS 收到顶级域名服务器的地址后,发起请求问“老二, 你能告诉我 www.server.com 的 IP 地址吗?”
  5. 顶级域名服务器说:“我给你负责www.server.com区域的权威 DNS 服务器的地址,你去问它应该能问到”。
  6. 本地 DNS 于是转向问权威 DNS 服务器:“老三,www.server.com对应的IP是啥呀?” server.com 的权威 DNS 服务器,它是域名解析结果的原出处。为啥叫权威呢?就是我的域名我做主。
  7. 权威 DNS 服务器查询后将对应的 IP 地址 X.X.X.X 告诉本地 DNS。
  8. 本地 DNS 再将 IP 地址返回客户端,客户端和目标建立连接。

域名解析的工作流程

三、TCP

HTTP 是基于 TCP 协议传输的,所以在这我们先了解下 TCP 协议。

3.1 TCP报文格式

TCP 包头格式

MTU 与 MSS

MSS:1500 - 20 (IP头) - 20 (TCP头) = 1460 (Bytes)

3.2 TCP报文

此时报文如下:

TCP 层报文

3.3 三次握手

  • 客户端发送⼀个TCPSYN=1Seq=X的包到服务器端口
  • 服务器发回SYN=1ACK=X+1Seq=Y的响应包
  • 客户端发送ACK=Y+1Seq=Z

3.4 传输

  1. TCP链接建⽴后发送HTTP请求

  2. 服务器接受请求并解析,将请求转发到服务程序,如虚拟主机使用HTTP Host头部判断请求的服务程序

  3. 服务器检查HTTP请求头是否包含缓存验证信息,如果验证缓存新鲜,返回304等对应状态码

  4. 处理程序读取完整请求并准备HTTP响应,可能需要查询数据库等操作

  5. 服务器将响应报文通过TCP连接发送回浏览器

3.5 四次握手

浏览器接收HTTP响应,然后根据情况选择关闭TCP连接或者保留重用,关闭TCP连接的四次握⼿如下:

  • 主动⽅发送Fin=1, Ack=Z, Seq= X报文

  • 被动⽅发送ACK=X+1, Seq=Z报文

  • 被动⽅发送Fin=1, ACK=X, Seq=Y报文

  • 主动⽅发送ACK=Y, Seq=X报文

四、准备渲染

  1. 浏览器检查响应状态码:是否为1XX,3XX, 4XX, 5XX,这些情况处理与2XX不同
  2. 如果资源可缓存,进行缓存
  3. 对响应进行解码(例如gzip压缩)
  4. 根据资源类型决定如何处理(假设资源为HTML文档)
  5. 解析HTML文档构件DOM树下载资源构造CSSOM树执行js脚本,这些操作没有严 格的先后顺序,以下分别解释:

4.1 构建DOM树

HTML 通过HTML解析器转成DOM Tree

  • Tokenizing:根据HTML规范将字符流解析为标记
  • Lexing:词法分析将标记转换为对象并定义属性和规则
  • DOM construction:根据HTML标记关系将对象组成DOM

解析过程中遇到图⽚、样式表、js文件,启动下载

4.2 构建CSSOM树

CSS按照CSS规则和CSS解析器转成CSSOM Tree

  • Tokenizing:字符流转换为标记流
  • Node:根据标记创建节点
  • CSSOM:节点创建CSSOM

4.3 构建渲染树

根据DOM树和CSSOM树构建

  1. 从DOM树的根节点遍历所有可见节点(不可见节点:script/meta等本身不可见的标签、被css隐藏的节点、……)
  2. 对每一个可见节点,找到恰当的CSSOM规则并应用
  3. 发布可视节点的内容以及计算样式

4.4 js解析

  • 浏览器创建Document对象并解析HTML,将解析到的元素和文本节点添加到文档中,此时document.readystate为loading

  • HTML解析器遇到没有async和defer的script时,将他们添加到文档中,然后执行行内 或外部脚本。这些脚本会同步执行,并且在脚本下载和执行时解析器会暂停。这样就可以用document.write()把文本插⼊到输⼊流中。同步脚本经常简单定义函数和注册事件处理程序,他们可以遍历和操作script和他们之前的文档内容

  • 当解析器遇到设置了async属性的script时,开始下载脚本并继续解析文档。脚本会在它 下载完成后尽快执行,但是解析器不会停下来等它下载。异步脚本禁止使用 document.write(),它们可以访问⾃⼰script和之前的文档元素

  • 当文档完成解析,document.readState变成interactive

  • 所有defer脚本会按照在文档出现的顺序执行,延迟脚本能访问完整文档树,禁止使用 document.write()

  • 浏览器在Document对象上触发DOMContentLoaded事件

  • 此时文档完全解析完成,浏览器可能还在等待如图⽚等内容加载,等这些内容完成载⼊ 并且所有异步脚本完成载⼊和执行,document.readState变为complete,window触发 load事件

然后就是显示页面了

那么数据包具体是怎么传输的呢?别急 还有呢

五、IP

TCP 模块在执行连接、收发、断开等各阶段操作时,都需要委托 IP 模块将数据封装成网络包发送给通信对象。

5.1 IP报文格式

IP 包头格式

因为 HTTP 是经过 TCP 传输的,所以在 IP 包头的协议号,要填写为 06(十六进制),表示协议为 TCP。

5.2 源IP地址的选择

我们假设 Web 服务器的目标地址是 192.168.10.200

路由规则判断

  1. 首先先和第一条目的子网掩码(Genmask)进行 与运算,得到结果为 192.168.10.0,但是第一个条目的 Destination192.168.3.0,两者不一致所以匹配失败。
  2. 再与第二条目的子网掩码进行 与运算,得到的结果为 192.168.10.0,与第二条目的 Destination 192.168.10.0 匹配成功,所以将使用 eth1 网卡的 IP 地址作为 IP 包头的源地址。

那么假设 Web 服务器的目标地址是 10.100.20.100,那么依然依照上面的路由表规则判断,判断后的结果是和第三条目匹配。

第三条目比较特殊,它目标地址和子网掩码都是 0.0.0.0,这表示默认网关,如果其他所有条目都无法匹配,就会自动匹配这一行。并且后续就把包发给路由器,Gateway 即是路由器的 IP 地址。

5.3 IP报文

此时报文如下:

IP 层报文

六、MAC

生成了 IP 头部之后,接下来网络包还需要在 IP 头部的前面加上 MAC 头部

6.1 MAC报文格式

MAC 包头格式

在 MAC 包头里需要发送方 MAC 地址接收方目标 MAC 地址,用于两点之间的传输

一般在 TCP/IP 通信里,MAC 包头的协议类型只使用:

  • 0800 : IP 协议
  • 0806 : ARP 协议

6.2 MAC地址确定

发送方的 MAC 地址获取就比较简单了,MAC 地址是在网卡生产时写入到 ROM 里的,只要将这个值读取出来写入到 MAC 头部就可以了。

接收方的 MAC 地址获取:

  • 先查询 ARP 缓存,如果其中已经保存了对方的 MAC 地址,就不需要发送 ARP 查询,直接使用 ARP 缓存中的地址。
  • 而当 ARP 缓存中不存在对方 MAC 地址时,则发送 ARP 广播查询。

ARP 广播

6.3 MAC报文

MAC 层报文

七、网卡

网络包只是存放在内存中的一串二进制数字信息,没有办法直接发送给对方。因此,我们需要将数字信息转换为电信号,才能在网线上传输,也就是说,这才是真正的数据发送过程。

负责执行这一操作的是网卡,要控制网卡还需要靠网卡驱动程序

网卡驱动获取网络包之后,会将其复制到网卡内的缓存区中,接着会在其开头加上报头和起始帧分界符,在末尾加上用于检测错误的帧校验序列

数据包

最后网卡会将包转为电信号,通过网线发送出去。

八、交换机

下面来看一下包是如何通过交换机的。交换机的设计是将网络包原样转发到目的地。交换机工作在 MAC 层,也称为二层网络设备

8.1 交换机的包接收操作

首先,电信号到达网线接口,交换机里的模块进行接收,接下来交换机里的模块将电信号转换为数字信号。

然后通过包末尾的 FCS 校验错误,如果没问题则放到缓冲区。这部分操作基本和计算机的网卡相同,但交换机的工作方式和网卡不同。

计算机的网卡本身具有 MAC 地址,并通过核对收到的包的接收方 MAC 地址判断是不是发给自己的,如果不是发给自己的则丢弃;相对地,交换机的端口不核对接收方 MAC 地址,而是直接接收所有的包并存放到缓冲区中。因此,和网卡不同,交换机的端口不具有 MAC 地址

将包存入缓冲区后,接下来需要查询一下这个包的接收方 MAC 地址是否已经在 MAC 地址表中有记录了。

交换机的 MAC 地址表主要包含两个信息:

  • 一个是设备的 MAC 地址,
  • 另一个是该设备连接在交换机的哪个端口上。

交换机的 MAC 地址表

如果有,则直接转发+学习;如果没有,则泛洪+学习

九、路由器

网络包经过交换机之后,现在到达了路由器,并在此被转发到下一个路由器或目标设备。

这一步转发的工作原理和交换机类似,也是通过查表判断包转发的目标。

不过在具体的操作过程上,路由器和交换机是有区别的。

  • 因为路由器是基于 IP 设计的,俗称三层网络设备,路由器的各个端口都具有 MAC 地址和 IP 地址;
  • 交换机是基于以太网设计的,俗称二层网络设备,交换机的端口不具有 MAC 地址。

9.1 路由器的包接收操作

首先,电信号到达网线接口部分,路由器中的模块会将电信号转成数字信号,然后通过包末尾的 FCS 进行错误校验。

如果没问题则检查 MAC 头部中的接收方 MAC 地址,看看是不是发给自己的包,如果是就放到接收缓冲区中,否则就丢弃这个包。

总的来说,路由器的端口都具有 MAC 地址,只接收与自身地址匹配的包,遇到不匹配的包则直接丢弃。

9.2 查询路由表确定输出端口

完成包接收操作之后,路由器就会去掉包开头的 MAC 头部。

MAC 头部的作用就是将包送达路由器,其中的接收方 MAC 地址就是路由器端口的 MAC 地址。因此,当包到达路由器之后,MAC 头部的任务就完成了,于是 MAC 头部就会被丢弃

接下来,路由器会根据 MAC 头部后方的 IP 头部中的内容进行包的转发操作。

转发操作分为几个阶段,首先是查询路由表判断转发目标。

路由器转发

找不到匹配路由时,就会选择默认路由,路由表中子网掩码为 0.0.0.0 的记录表示「默认路由」。

9.3 路由器的发送操作

首先,我们需要根据路由表的网关列判断对方的地址。

  • 如果网关是一个 IP 地址,则这个IP 地址就是我们要转发到的目标地址,还未抵达终点,还需继续需要路由器转发。
  • 如果网关为空,则 IP 头部中的接收方 IP 地址就是要转发到的目标地址,也是就终于找到 IP 包头里的目标地址了,说明已抵达终点

知道对方的 IP 地址之后,接下来需要通过 ARP 协议根据 IP 地址查询 MAC 地址,并将查询的结果作为接收方 MAC 地址。

路由器也有 ARP 缓存,因此首先会在 ARP 缓存中查询,如果找不到则发送 ARP 查询请求。

接下来是发送方 MAC 地址字段,这里填写输出端口的 MAC 地址。还有一个以太类型字段,填写 0800 (十六进制)表示 IP 协议。

网络包完成后,接下来会将其转换成电信号并通过端口发送出去。这一步的工作过程和计算机也是相同的。

发送出去的网络包会通过交换机到达下一个路由器。由于接收方 MAC 地址就是下一个路由器的地址,所以交换机会根据这一地址将包传输到下一个路由器。

接下来,下一个路由器会将包转发给再下一个路由器,经过层层转发之后,网络包就到达了最终的目的地。

不知你发现了没有,在网络包传输的过程中,源 IP 和目标 IP 始终是不会变的,一直变化的是 MAC 地址,因为需要 MAC 地址在以太网内进行两个设备之间的包传输。

参考链接

2.2 键入网址到网页显示,期间发生了什么? | 小林coding (xiaolincoding.com)

大厂常问:输入URL到显示页面的全过程(敲详细)_---------------------------message from webpage----CSDN博客

详细拆解导航流程:从输入URL到页面展示,这中间发生了什么?-腾讯云开发者社区-腾讯云 (tencent.com)