浏览器如何获取并展示网页内容的完整流程

7/25/2025, 7:59:50 PM

本文系统梳理了浏览器从用户输入网址到页面呈现的全过程,包括缓存机制(强缓存与协商缓存)、DNS 解析、TCP 连接建立、TLS 加密通信、HTTP 请求与响应,以及 HTML 的解析与渲染流程。通过详细步骤解释浏览器如何定位服务器、取回资源,并最终构建 DOM、CSSOM 与渲染树,将网页内容呈现在用户面前,让你全面理解浏览器背后的运作原理。

浏览器如何找到文章在哪

强缓存

当你输入linhanxi.cn并回车,浏览器会先看看强缓存是否存在 && 未过期 && 被允许使用,如果是,则直接返回强缓存的文件。如何判断缓存是否过期呢?

  1. 先看响应头的 Cache-Control,如果有 max-age 且 max-age + Date > 本地时间,则强缓存新鲜;
  2. 没有 Cache-Control,再看 Expires,Expires > 本地时间,则强缓存新鲜;

另外 Cache-Control 还有丰富的值来控制缓存的行为,常见包括:

  • no-cache:不使用强缓存
  • no-store:不使用任何缓存
  • public:可以被任何人缓存
  • private:只能被用户浏览器缓存

DNS 解析

强缓存不可用的话就要进行 DNS 解析了,即从你输入的域名linhanxi.cn来找到它指向的 ip。路径是浏览器缓存 -> 操作系统缓存 -> 路由器缓存 -> DNS 系统(根域名服务器 -> 顶级域名服务器 -> 权威域名服务器),过程中一旦找到 IP,即定位到存放文章的服务器。

浏览器如何取回文章

找到服务器了就可以想办法取回文章了。我们需要根据 TCP 来建立连接,并通过 TLS 来加密我们的对话。

TCP

  1. 客户端发送 SYN 包。其中 SYN = 1,并生成随机序列号 seq = x;
  2. 服务端收到后,发送 SYN - ACK 包。其中 SYN = 1,ACK = 1,ack = x + 1,并生成随机序列号 seq = y;
  3. 客户端收到后,发送 ACK 包,其中 ACK = 1,ack = y + 1。

当服务端收到 ACK 包且内容正确时,此时双端的收发能力得到验证,建立连接成功!

TLS 1.3

  1. 客户端发送可选加密算法、随机数 x、它的 ECDHE 临时公钥;
  2. 服务端发送选定加密算法、随机数 y、它的 ECDHE 临时公钥;
  3. 双端用自己的密钥 + 对方的公钥生成预主密钥,并结合双方随机数通过密钥派生函数计算会话密钥;
  4. 服务端发送握手内容 + 私钥加密的签名、CA 证书;
  5. 客户端用 CA 证书上的服务器公钥验证签名和握手内容,确认服务器是它本服务器;
  6. 握手结束,后续用会话密钥加密通信;

此时我们就可以在这基础之上发送 http 请求了!

协商缓存

发送 http 请求资源的时候,如果发现本地缓存的文件和服务器的文件是一样的,那么直接使用本地缓存就好了,这时就要用到协商缓存来判断。

  1. 服务器返回资源的时候会在响应头带上 Etag,这个唯一标识符只在文件内容被修改的时候才会修改(具体因什么行为而修改是可以自己制定的,但我认为这样最优)。客户端下次再请求的时候在请求头上带上 If-None-Match,值为 Etag 的值。服务器如果比对发现 Etag = If-None-Match,就返回 304 状态码及无内容,浏览器收到状态码后会自动使用本地缓存。
  2. 如果没有 Etag,那么可以看看 Last-Modified —— 文件最后修改时间。和上面一样,服务器在响应头带上 Last-Modified,客户端会在下次请求带上 If-Modified-Since,服务器比对两者值相同,则返回 304 状态码及无内容,浏览器使用本地缓存。
  3. 如果失效或根本没有配置协商缓存,那就正常返回资源。

此时我们终于拿回了 html 文件了!

浏览器如何让大家看到文章

解析 html

拿到 html 文件后,浏览器就开始从上至下解析 html 文件,根据 html 内容构建 DOM 树。其中:

  • 如果遇到了 css 文件,那么立即下载并开始构建 CSSOM 树。
  • 如果遇到了 js 文件,就要看看 script 所带的属性:
    • 没有 defer 和 async:停止解析,立即下载 js 文件并执行;
    • defer:立即下载,待 DOM 树构建之后按顺序执行;
    • async:立即下载,下载完之后立即执行;

在 DOM 树和 CSSOM 树都构建完成之后,把它们合成渲染树。接着根据渲染树回流——计算元素大小和位置、重绘——把像素绘制到屏幕上,合成多个图层并最终展示。