从 URL 输入到页面渲染的全过程

前言

当用户在浏览器地址栏输入 URL 并按下回车键时,背后涉及了从物理层到应用层、从客户端到服务器端的复杂协作。本文将详细解构这一过程中的关键技术环节。

1. 协议预处理与 HSTS 机制

在发起网络请求前,现代浏览器会执行安全策略检查。

1.1 HSTS (HTTP Strict Transport Security)

为了防范中间人攻击(如 SSL Striping),浏览器会检查本地的 HSTS 列表,判断该域名是否强制要求使用 HTTPS 访问。

1.1.1 动态记录(HSTS Cache)

  • 原理:当浏览器首次通过 HTTPS 成功访问站点,且服务器响应头包含 Strict-Transport-Security: max-age=... 时,浏览器会将该域名记录在本地缓存中。
  • 局限性:存在“首次访问安全漏洞(TOFU)”,即第一次建立连接时若被劫持,浏览器无法感知。

1.1.2 预加载列表(HSTS Preload List)

  • 原理:由 Google 维护并被主流浏览器集成的硬编码列表。
  • 优势:即使是首次访问,浏览器也会直接根据列表强制发起 HTTPS 连接,实现全链路安全。

1.1.3 非 HSTS 场景的处理

  1. 显式重定向:若请求为 HTTP,服务器返回 301/302 响应,并在 Location 首部指明 HTTPS 地址。
  2. 不安全访问:若服务器未配置强制加密,浏览器会标记“Not Secure”并继续使用 HTTP。
  3. 连接被拒绝:若服务器仅监听 443 端口,则 80 端口的 TCP 握手将失败,返回 ERR_CONNECTION_REFUSED

2. DNS 域名解析

将人类可读的域名转换为机器可识别的 IP 地址,遵循就近优先原则:

  1. 浏览器缓存:检查浏览器内存中是否存在未过期的 DNS 记录。
  2. 操作系统缓存:检查 OS 级 DNS 缓存及 hosts 静态映射文件。
  3. 递归查询 (Recursive Query):操作系统向 本地 DNS 服务器 (LDNS) 发起请求。
  4. 迭代查询 (Iterative Query):若 LDNS 无缓存,则由其代替用户向:
    • 根域名服务器获取顶级域名(TLD)服务器地址。
    • TLD 域名服务器(如 .com)获取权威域名服务器地址。
    • 权威域名服务器获取最终的 IP 地址记录。

3. 传输层:TCP 三次握手

在获取 IP 后,浏览器与服务器建立可靠的传输通道。

  • 第一次握手:客户端发送 SYN 报文,携带初始序列号 seq=x
  • 第二次握手:服务器返回 SYN+ACK 报文,确认号 ack=x+1,并携带自己的初始序列号 seq=y
  • 第三次握手:客户端发送 ACK 报文,确认号 ack=y+1

核心设计目的

  1. 防止历史连接重启:在不可靠网络中,防止旧的重复 SYN 包误建连接(见 RFC 793)。
  2. 同步初始序列号 (ISN):确保双方数据包的顺序性与可靠性。
  3. 资源分配确认:确保双方均具备发送与接收数据的能力。

4. 安全层:TLS/SSL 握手

在 TCP 连接之上,HTTPS 引入 TLS 协议进行身份核验与密钥协商。

4.1 身份认证与算法协商

  1. ClientHello:客户端发送支持的 TLS 版本、加密套件列表及 随机数 C
  2. ServerHello:服务器选择版本、套件,发送 随机数 S数字证书 (X.509)
  3. 证书验签:浏览器通过内置 CA 根证书验证证书链的签名、有效期及域名匹配性。

4.2 密钥交换 (Key Exchange)

  • 预主密钥 (Premaster Secret):浏览器生成一个随机数,使用证书中的公钥加密发送给服务器。
  • 主密钥生成:双方结合 随机数 C + 随机数 S + 预主密钥,通过 PRF 算法各自计算出对称加密所需的主密钥 (Master Secret)

4.3 确认安全传输

双方互发 ChangeCipherSpecFinished 报文,标志后续所有应用层数据将进行对称加密。

5. HTTP 请求构造与发送

连接就绪后,浏览器封装符合协议标准的请求报文。

  • 请求行:定义方法(GET/POST)、路径(URI)及版本(HTTP/1.1)。
  • 请求头
    • Host:指定目标服务器域名(虚拟主机支持的关键)。
    • Cookie:携带本地存储的状态信息。
    • Cache-Control:指示缓存策略(如 max-age=0)。
  • 请求体:POST 提交的数据或 JSON 负载。

6. 服务器处理与响应模型

6.1 负载均衡与网关

  1. 四层负载均衡 (L4):基于 IP+端口转发(如 LVS),侧重吞吐量。
  2. 七层负载均衡 (L7):基于 URL、Header 路由(如 Nginx, ELB),侧重业务灵活性。
  3. VIP (虚拟 IP):通过 Keepalived 等工具实现高可用,当主服务器故障时,VIP 漂移至备份节点。

6.2 后端逻辑处理

  • 静态处理:Nginx 直接从磁盘或内存缓存中读取静态资源。
  • 动态处理:API 网关转发至微服务,涉及身份认证、限流、数据库查询(Cache Aside 模式)及业务计算。

7. 浏览器渲染管线 (Rendering Pipeline)

浏览器接收到响应体(HTML 字节流)后,启动渲染引擎:

  1. DOM 构建:字节流 -> 字符 -> Token -> Nodes -> DOM Tree
  2. CSSOM 构建:解析样式表,生成 CSSOM Tree
  3. 布局树 (Layout Tree):结合 DOM 和 CSSOM,剔除 display: none 等不可见节点。
  4. 分层 (Layering):针对 3D 转换、z-index 等生成专用的渲染层。
  5. 光栅化 (Rasterization):将图层转换为像素点,通常利用 GPU 加速(GPU Rasterization)。
  6. 合成 (Compositing):合成线程将图块(Tiles)组合并提交给显卡显示。

脚本阻塞机制

  • Default<script> 会阻塞 DOM 构建。
  • async:异步下载,下载完立即执行,可能阻塞 DOM。
  • defer:异步下载,待 DOM 解析完成后按顺序执行。

8. 连接释放:TCP 四次挥手

通信结束后,双向连接需有序关闭。

  1. FIN_WAIT_1:主动方发送 FIN
  2. CLOSE_WAIT:被动方回复 ACK,此时处于半关闭状态,可继续发送剩余数据。
  3. LAST_ACK:被动方发送 FIN
  4. TIME_WAIT:主动方回复最后一个 ACK

为什么需要 TIME_WAIT (2MSL)?

  1. 可靠地终止连接:确保最后一个 ACK 能到达被动方,若丢失可重传。
  2. 防止“已失效报文”干扰:确保旧连接产生的所有报文都在网络中消失,避免干扰后续相同四元组的新连接。

9. WebSocket 实时通信扩展

对于高频实时场景,HTTP 握手后可升级为 WebSocket。

  • 握手协议:借用 HTTP 协议,Header 包含 Upgrade: websocketSec-WebSocket-Key
  • 状态码 101:代表协议切换成功。
  • 特点:全双工通信、二进制帧结构、极低头部开销。

参考资料

  • RFC 7230:HTTP/1.1 Message Syntax and Routing
  • RFC 8446:The TLS Protocol 1.3
  • Chromium Blog:Inside look at modern web browser
  • MDN Web Docs:Critical rendering path

从 URL 输入到页面渲染的全过程
https://yicizhang00.github.io/posts/基础理论/计算机网络/URL输入浏览器发生了什么/
作者
Yici Zhang
发布于
2026年6月18日
许可协议