浏览器发送网页详细过程分解
好的,这是一个非常经典且重要的面试题和技术知识点。浏览器从发起 HTTP 请求到最终渲染出网页的过程,可以清晰地分为以下几个核心阶段。
为了更直观地理解,你可以将整个过程想象成寄送和组装一个乐高包裹:
- DNS 解析:查收件人(服务器)的确切地址。
- 建立 TCP 连接:开车到收件地址,敲开门并建立联系。
- 发送 HTTP 请求:把想要的乐高套装型号(请求信息)告诉收件人。
- 服务器处理请求并返回 HTTP 响应:收件人找到对应的乐高盒子(资源),打包好给你。
- 浏览器解析和渲染页面:你收到包裹,打开盒子,按照说明书一步步拼装乐高。
- 连接结束:完成后,你们互相道别(关闭连接)。
详细过程分解
阶段一:DNS 解析 (Domain Name System)
- 目的:将人类可读的域名 (如
www.google.com
) 转换为机器可读的 IP 地址 (如142.251.42.206
)。 - 过程:
- 浏览器缓存:浏览器首先检查自身缓存中是否有该域名的 IP。
- 系统缓存:如果浏览器没有,检查操作系统的 hosts 文件和缓存。
- 路由器缓存:查询路由器缓存。
- ISP DNS 服务器:向互联网服务提供商 (ISP) 的 DNS 服务器发起查询。
- 递归/迭代查询:如果 ISP 的服务器也没有,它会从 DNS 根服务器开始,依次向顶级域服务器(.com)、权威域服务器(google.com)进行迭代查询,最终找到正确的 IP。
- 结果:拿到目标服务器的 IP 地址。
阶段二:建立 TCP 连接 (三次握手)
- 目的:在浏览器和服务器之间建立一个可靠的、面向连接的通信通道。HTTP 协议依赖于 TCP 协议来传输数据。
- 过程 (三次握手):
- SYN:浏览器向服务器发送一个 SYN (Synchronize Sequence Numbers) 包,请求建立连接。
- SYN-ACK:服务器收到后,如果同意连接,会回复一个 SYN-ACK 包作为应答。
- ACK:浏览器收到 SYN-ACK 后,再向服务器发送一个 ACK (Acknowledgment) 包确认。连接至此建立。
- 如果使用 HTTPS:在 TCP 连接建立后,还会进行 TLS 握手,交换密钥、验证证书,建立一个安全的加密通道。这通常需要额外的往返。
阶段三:浏览器发送 HTTP 请求
- 目的:告诉服务器客户端需要什么资源。
- 内容:一个标准的 HTTP 请求报文,通过已建立的 TCP 连接发送出去。报文主要包括:
- 请求行:包含方法 (GET, POST 等)、请求的 URL 路径、HTTP 版本。
- 请求头 (Headers):包含大量元信息,如:
Host
: 目标域名User-Agent
: 浏览器身份标识Accept
: 客户端能处理的内容类型 (如text/html
)Cookie
: 携带本地cookie信息
- 请求体 (Body):主要存在于 POST、PUT 等方法中,包含要提交的数据 (如表单数据、JSON 等)。GET 请求没有请求体。
阶段四:服务器处理请求并返回 HTTP 响应
- 目的:处理请求并返回客户端所需的数据。
- 服务器端过程:
- 服务器(如 Nginx, Apache)接收请求。
- 可能将请求转发给后端应用服务器(如 Tomcat, Django, Node.js)。
- 后端程序处理业务逻辑(查询数据库、计算等)。
- 生成一个 HTTP 响应报文。
- 响应报文:
- 状态行:包含 HTTP 版本、状态码 (如
200 OK
,404 Not Found
) 和状态信息。 - 响应头 (Headers):包含响应的元信息,如:
Content-Type
: 响应体的数据类型 (如text/html; charset=utf-8
)Content-Length
: 响应体的长度Set-Cookie
: 设置 Cookie 到浏览器
- 响应体 (Body):真正的请求资源内容,如 HTML 文档、图片数据、JSON 数据等。
- 状态行:包含 HTTP 版本、状态码 (如
阶段五:浏览器解析和渲染页面
这是最复杂的一步。浏览器拿到 HTML 响应后,开始解析和渲染:
- 解析 HTML,构建 DOM 树:
- 浏览器解析 HTML 字节流,将其转换为令牌 (Tokens),然后构建成DOM(文档对象模型)树。这是一个表示页面结构的树状结构。
- 解析 CSS,构建 CSSOM 树:
- 遇到
<link>
或<style>
标签时,开始解析 CSS,构建 CSSOM(CSS对象模型)树。它决定了每个节点的样式。
- 遇到
- 合并 DOM 和 CSSOM,构建渲染树 (Render Tree):
- 将 DOM 树和 CSSOM 树合并,生成渲染树。渲染树只包含需要在屏幕上显示的元素(如不包含
display: none
的元素)。
- 将 DOM 树和 CSSOM 树合并,生成渲染树。渲染树只包含需要在屏幕上显示的元素(如不包含
- 布局 (Layout / Reflow):
- 计算渲染树中每个元素在设备视口 (viewport) 内的确切位置和大小。这个阶段就是“计算盒模型”。
- 绘制 (Painting):
- 将布局计算后的每个节点,转换为屏幕上的实际像素。包括绘制文本、颜色、图像、边框、阴影等。
- 合成 (Compositing):
- 将各层绘制内容合成为一个完整的页面显示到屏幕上。
注意:解析 HTML 时,如果遇到 <script>
标签(尤其是没有 async
或 defer
属性的),会停止 HTML 解析,先下载并执行 JavaScript。因为 JS 可能会修改 DOM 结构。
阶段六:断开连接 (四次挥手)
- 目的:完成数据传输后,安全地关闭 TCP 连接,释放系统资源。
- 过程 (四次挥手):
- FIN:浏览器(或服务器)发送 FIN 包,表示数据发送完毕,请求关闭连接。
- ACK:服务器收到 FIN 后,发送 ACK 包进行确认。
- FIN:服务器处理完所有数据后,也发送一个 FIN 包给浏览器。
- ACK:浏览器收到 FIN 后,发送最后的 ACK 包确认。等待一段时间后,连接正式关闭。
总结流程图
graph TDA[用户输入URL并回车] --> B[DNS解析]B --> C[获取服务器IP地址]C --> D[TCP三次握手]D --> E[发送HTTP请求]E --> F[服务器处理并返回响应]F --> G[浏览器解析渲染]subgraph G [浏览器解析渲染]G1[解析HTML构建DOM树]G2[解析CSS构建CSSOM树]G3[合并生成渲染树]G4[布局 Layout]G5[绘制 Painting]endG --> H[TCP四次挥手断开连接]H --> I[页面展示完成]