引言
当我们打开浏览器并在地址栏中输入一个网址时,直到最终看到页面完全加载完毕,背后发生了许多复杂的交互过程。本文将逐步介绍这一过程的关键步骤,包括 DNS 解析、TCP 连接建立、HTTP 数据传输、HTTPS 加密、页面渲染。
一: 域名解析
当我们在浏览器中输入一个 URL 时,第一步是通过 DNS(Domain Name System)解析将域名转换为 IP 地址。这个过程大致分为以下几个步骤:
- 本地域名服务器查找缓存:浏览器首先检查本地缓存中是否有对应的 IP 地址记录。
- 到根域名服务器查找缓存:如果本地缓存中没有记录,则浏览器会向根域名服务器发起请求。
- 到顶级域名服务器查找缓存:根域名服务器会指引浏览器到相应的顶级域名服务器(例如 .com 服务器)。
- 目标服务器查找缓存:最后,顶级域名服务器会将请求转发到具体的域名服务器。
- 本地缓存 IP 地址:获取到 IP 地址后,浏览器会将其缓存起来,以便下次更快地访问同一网站。
二. TCP 建立连接
获得 IP 地址后,浏览器会通过 TCP 协议建立连接。
2.1:TCP
TCP是互联网中最核心的协议之一,它位于 OSI 模型的传输层,负责在应用程序之间提供可靠的数据传输服务,拥有头部和状态机,这里介绍下在面试中常考到的几点
URG = 1
:紧急信息ACK = 1
:有效字段SYN = 1 & ACK = 0
:请求报文SYN = 1 & ACK = 1
:应答报文
2.2:TCP三次握手
- 客户端发送 SYN 报文:客户端向服务器发送一个带有 SYN 标志的报文,请求建立连接,客户端进入 SYN-SENT 状态。
- 服务器回应 SYN+ACK:服务器接收到请求后,会发送一个带有 SYN 和 ACK 标志的报文,确认连接,服务端进入 SYN-RECEIVED 状态。
- 客户端发送 ACK:客户端再发送一个带有 ACK 标志的报文,确认收到服务器的 SYN+ACK 报文。
2.3:为什么不是两次握手
如果两次,会导致服务器资源浪费,当客户端向服务端发送建立连接请求A,但是因为网络问题导致A请求超时,TCP的超时重传机制会再次发送一个新的建立连接请求B,当B被应答后,数据通讯完成后释放连接,双方进入close状态,一旦此时请求A再次出现,那么服务端会认为又有客户端要跟它建立连接,从而应答并进入SYN-RECEIVED状态等待数据传输,造成服务端资源浪费
三: HTTP 数据传输
连接建立后,浏览器会通过 HTTP向服务器发送请求。HTTP 经历了几个版本的发展,我们要熟悉了解历史版本的缺点与改进,才能理解现在普及的2.0版本以及未来将普及的3.0版本
3.1:HTTP/0.9
- 基于TCP协议建立连接 -> 发送请求行 GET/index.html -> 服务端接收到请求,读取html文件,以ASCII字母流返回给客户端
- 只有请求行,没有请求体
- 服务器没有响应头,只有返回体
- 都是用ASCII字符串传输
3.2:HTTP/1.0
-
引入请求头和响应头
- 请求头: accept: text/html | accept-encoding:gzip,deflate,br | accept-Charset:utf-8 | accept-language: zh-CN,zh
- 响应头:content-encoding:br | content-type:text/html;charset=utf-8
-
引入了状态码
-
引入了 HTTP Cache 机制
3.3:HTTP/1.1
1.0时代,http是短连接,随着浏览器的普及,单个页面中的各种文件图片资源越来越多,这样每次请求一个资源都要建立连接,传输数据,断开连接,增加了很多不必要的开销。所以1.1增加了持久连接的方法,建立一个TCP连接,可以传输多个http请求
- 请求头Connection:close 可以关闭持久连接
- HTTP队头阻塞:一次连接可以发多个请求,但是请求之间必须等待前一个请求响应结束才可以发第二个请求
- 提供了虚拟机支持Host xxx
- Chunk transfer机制:服务端将数据分割成若干个,任意大小数据块上标记了数据块的大小,最后使用一个长度为0的空数据块作为传输完成的标志
- Cookie机制
3.4:HTTP/2
- 1.1对带宽的利用率底下原因:
-
- TCP的慢启动:tcp协议采用了一个由慢到快的传输加速度
-
- 同时开启多个TCP连接,这些连接之间相互竞争带宽,会影响关键资源的下载速度
-
- http队头阻塞问题
-
- 2的多路复用
- 不允许同时建立多个TCP连接,一个域名只能建立一个tcp连接
- 采用二进制分帧层,将所有的请求处理为一帧一帧的请求,每一帧请求都带上独特的ID编号,服务端根据ID区分拼接完整请求体,并以同样的方式返回响应
3.5:HTTPS 加密
为了提高安全性,现代网页通常使用 HTTPS(HTTP Secure)。HTTPS 在 HTTP 的基础上加入了 SSL/TLS 加密层,使用对称加密和非对称加密的组合来保护数据传输的安全性。
1.对称加密:加密数据时使用的密钥必须与解密数据时使用的密钥相同
- 相同的密钥用于加密和解密。
- 速度较快,适合加密大量数据。
- 密钥管理问题:密钥必须在双方之间安全地交换。
2.非对称加密:非对称加密使用一对密钥:公钥和私钥。公钥用于加密数据,而私钥用于解密数据。公钥可以公开发布,任何人都可以用它来加密消息,但只有拥有相应私钥的人才能解密这些消息
- 公钥用于加密,私钥用于解密。
- 密钥管理容易:只需要保护好私钥。
- 速度较慢,适合加密少量数据或用于密钥交换。
3.6:HTTP/3:
- 2.0 是基于TCP制定的,存在TCP队头阻塞问题
- TCP慢启动
- TCP在传输过程中,一旦发生单个数据包丢失,其他后续的数据包会暂停发送,等重新将丢失的数据包整理好之后,再次启动传输
- TCP僵化
- HTTP3.0采用QUIC协议,即 TCP + UDP
- 实现了TCP的可靠性
- 实现了TLS加密
- 实现了多路复用
- 实现了快速握手
- TCP与UDP区别
- TCP:
- 面向有连接,TCP一定要建立连接
- 连接更加可靠,可靠性体现在:有流量拥塞控制
- 有序性
- DCP:
- 无连接
- 不可靠:没有流量拥塞控制,丢包不管
- 高效:对实时性要求很高的场景:直播,视频通话
- TCP:
四: TCP 断开连接
数据传输完成后,浏览器和服务器需要断开 TCP 连接。这个过程通常被称为“四次挥手”:
1.客户端向服务端发送释放连接
2.服务端接收到释放连接的请求,进入CLOSE_WAIT状态,向客户端发送同意断开的应答
3.服务端向客户端发送还未发送完的数据,服务端进入LAST_ACK状态
4.客户端接收到同意的应答后,向服务端发送确认接受应答,双方都进入CLOSE状态
五: 页面渲染过程
数据传输完成后,浏览器开始解析 HTML 并构建 DOM 树。接下来的步骤包括:
- 解析 HTML:浏览器解析 HTML 文件,构建 DOM 树。
- 解析 CSS:浏览器解析 CSS 文件,构建 CSSOM 树。
- 构建渲染树:将 DOM 树和 CSSOM 树合并,创建渲染树。
- 布局计算:计算每个元素的位置和尺寸,这可能会触发回流。
- 绘制:将渲染树中的元素绘制到屏幕上,可能会触发重绘。
回流与重绘
- 回流:当页面的几何结构发生改变时(例如元素的尺寸、位置变化),浏览器需要重新计算布局,这个过程称为回流。
- 重绘:当元素的外观发生改变但布局未变时(例如颜色变化),浏览器仅需更新视觉效果,这称为重绘。
另外在渲染过程中,浏览器会维护一个渲染队列,当改变元素的几何属性导致回流发生时,回流行为会被加入到渲染队列中,在达到阈值或者一定时间之后会一次性将渲染队列中所有的回流生效