从输入网址到页面展示的过程

298 阅读4分钟
1. 输入URL → 2. DNS解析 → 3. TCP握手 → 4. TLS握手 → 
5. HTTP请求 → 6. 服务器处理 → 7. 响应返回 → 
8. 解析HTML → 9. 构建DOM/CSSOM → 10. 渲染树 → 
11. 布局 → 12. 绘制 → 13. 交互

1. 输入网址并解析

  • 用户输入:在浏览器地址栏输入URL(如 https://www.example.com),浏览器会检查输入的内容是否是有效的URL或搜索关键词。
  • URL解析:浏览器解析URL的协议(https)、域名(www.example.com)、端口(默认443)、路径(/)等。

2. DNS 域名解析

  • 浏览器缓存:检查本地缓存是否有域名对应的IP地址。
  • 系统缓存:若浏览器无缓存,检查操作系统缓存(如Windows的hosts文件)。
  • 路由器缓存:查询本地路由器缓存。
  • ISP DNS服务器:若以上均未命中,向ISP(互联网服务提供商)的DNS服务器发起递归查询。
  • 递归查询
    • 根DNS服务器 → 顶级域服务器(如.com) → 权威DNS服务器(如example.com) → 返回IP地址。
  • DNS响应:最终获得域名对应的IP地址(如 93.184.216.34)。
+-------------------------------------------------------------------+
|                            DNS查询层级                             |
+---------------------+---------------------+-----------------------+
|       根DNS         |      顶级域DNS       |      权威DNS           |
|      (.)            |      (.com)         |    (example.com)      |
+----------+----------+----------+----------+------------+----------+
           |                    |                       |
           | 1. 查询".com在哪?" |                       |
           +------------------->|                       |
                                |                       |
                                | 2. 查询"example.com在哪?" |
                                +----------------------->|
                                                        |
                                                        | 3. 返回IP地址
                                                        +---------+
                                                                 |
                                                                 v
                                                          +-----------------+
                                                          |  93.184.216.34  |
                                                          | (example.com IP)|
                                                          +-----------------+

3. 建立TCP连接(三次握手)

  • SYN:客户端发送SYN包(同步序列编号)到服务器,进入SYN_SENT状态。
  • SYN-ACK:服务器收到SYN后返回SYN+ACK包,进入SYN_RECEIVED状态。
  • ACK:客户端发送ACK包确认,双方进入ESTABLISHED状态,完成三次握手。
  • HTTPS额外步骤:若是HTTPS,还需进行TLS握手(协商加密算法、交换密钥等)。
建立TCP连接(三次握手)
客户端           服务器
  |---- SYN ---->|  (序列号:x)
  |<-- SYN+ACK --|  (序列号:y, 确认号:x+1)
  |---- ACK ---->|  (确认号:y+1)
TLS握手(HTTPS安全连接)
1. ClientHello  → 支持的加密套件(如TLS_ECDHE_RSA)
2. ServerHello ← 选定套件 + 证书
3. 证书验证 → 生成会话密钥
4. 加密通信开始

4. 发送HTTP请求

  • 请求报文:浏览器构造HTTP请求,包含:
    • 请求行(如 GET / HTTP/1.1
    • 请求头(如 Host: www.example.comUser-AgentAccept等)
    • 请求体(GET请求通常为空,POST可能有数据)。
  • 发送请求:通过TCP连接发送到服务器。
GET / HTTP/1.1
Host: www.example.com
User-Agent: Mozilla/5.0
Accept: text/html, */*

5. 服务器处理请求

  • Web服务器(如Nginx/Apache)接收请求,根据路径路由到对应的处理程序。
  • 后端处理:动态内容(如PHP/Node.js)可能查询数据库,生成HTML。
  • 响应生成:服务器返回HTTP响应,包含:
    • 状态行(如 HTTP/1.1 200 OK
    • 响应头(如 Content-Type: text/html
    • 响应体(HTML内容)。
HTTP/1.1 200 OK
Content-Type: text/html
Content-Length: 1024

<!DOCTYPE html>
<html>...</html>

6. 浏览器解析与渲染

  1. 解析HTML
    • 构建DOM树:将HTML标签转换为树状结构。
    • 遇到<link>/<script>/<img>等标签时,加载外部资源(CSS/JS/图片)。
标签类型阻塞DOM解析阻塞页面渲染加载方式优化建议
<link>(CSS)同步加载内联关键CSS
<script>是(默认)同步加载使用async/defer
<img>异步加载懒加载
<html>
  <head>...</head>
  <body>
    <div>Hello World</div>
  </body>
</html>
  1. 解析CSS
    • 构建CSSOM树(样式规则树)。
div { color: red; }
  1. 合并DOM与CSSOM
    • 生成渲染树(Render Tree),排除不可见元素(如display:none)。
  2. 布局(Layout)
    • 计算每个节点的尺寸和位置(重排)。
┌─────────────┐
│   DIV       │
│  (red text) │
└─────────────┘
  1. 绘制(Paint)
    • 将渲染树转换为屏幕上的像素(重绘)。
  2. 执行JavaScript
    • 遇到<script>会阻塞DOM解析,除非标记为asyncdefer
+----------------+       +----------------+       +-----------------+
|     HTML       |       |     CSS        |       |  Render Tree    |
|   (DOM树)      |       |   (CSSOM树)    |       |  (渲染树)       |
+-------+--------+       +-------+--------+       +--------+--------+
        |                        |                         |
        | 1. 解析HTML标签         | 2. 解析CSS规则           | 3. 合并DOM+CSSOM
        |   生成DOM树              |   生成CSSOM树             |   排除不可见元素
        |                        |                         |
        v                        v                         v
+----------------+       +----------------+       +-----------------+
|                |       |                |       |  div (visible)  |
| <html>         |       |  body {margin:0}|       |  ┌────────────┐ |
|  <head>        |       |  div {color:red}|       |  │Hello World │ |
|  <body>        |       |                |       |  └────────────┘ |
|   <div>Hello   |       +----------------+       +-----------------+
|    World</div> |                                 |
|  </body>       |                                 |
| </html>        |                                 |
+----------------+                                 |
                                                   v
+-----------------------------+       +------------------------------+
|         Layout              |       |          Paint               |
|      (布局/重排)            |       |       (绘制/重绘)             |
| 计算元素大小和位置           |       |  将布局转换为屏幕像素         |
|   ┌──────────────────┐      |       |   +---------------------+    |
|   │div: width=200px  │      |       |   │ 渲染像素到屏幕        │    |
|   │ height=100px     │      |       |   │                     │    |
|   │ x=50, y=30       │      |       |   +---------------------+    |
|   └──────────────────┘      |       |                              |
+-----------------------------+       +------------------------------+

7. 加载动态资源

  • 异步请求:页面可能通过AJAX/Fetch动态加载数据。
  • 事件绑定:JavaScript为DOM元素绑定交互事件。

关键点总结

  1. DNS解析:将域名转换为IP地址。
  2. TCP连接:通过三次握手建立可靠传输。
  3. HTTP请求/响应:客户端与服务器通信。
  4. 渲染引擎工作:解析→渲染→交互。

示意图(简化版)

用户输入URL → DNS解析 → TCP握手 → HTTPS握手 → HTTP请求 → 服务器处理 → 返回响应 → 浏览器解析 → 渲染页面