经典:在浏览器地址栏输入信息到最终看到网页的全过程,涉及网络协议以及前后端技术
文章目录
- 流程总览
- 第一阶段:用户输入与浏览器解析
- 第二阶段:网络通信之旅(核心网络知识)
- 第三阶段:后端服务器处理(核心后端知识)
- 第四阶段:浏览器渲染页面(核心前端知识)
- 总结
流程总览
为了方便理解,我们可以先把整个流程简化成一个序列:
用户输入
-> 浏览器解析
-> DNS查询
-> TCP/IP连接
-> 发起HTTP(S)请求
-> 后端服务器处理
-> 后端服务器响应
-> 浏览器接收响应
-> 浏览器渲染页面
-> 渲染完成
第一阶段:用户输入与浏览器解析
当你在浏览器地址栏输入 https://www.google.com
并按下回车时,事情开始了。
-
输入解析 (URL Parsing):浏览器首先会解析你输入的内容。
- 它是什么? 它会判断你输入的是一个合法的 URL (Uniform Resource Locator),还是一个搜索关键词。如果是关键词,浏览器会使用其默认的搜索引擎来拼接成一个搜索 URL。
- URL结构分解:对于
https://www.google.com
这个 URL,浏览器会将其拆解为几个部分:https
: 协议 (Protocol),表示需要通过安全套接字层 (SSL/TLS) 进行加密通信。www.google.com
: 域名 (Domain Name),即我们要访问的服务器的地址。/(默认)
: 路径 (Path),这里没有显式路径,默认为根路径。?(无)
: 查询参数 (Query Parameters),这里没有。
-
缓存检查 (Cache Check):在发起网络请求之前,聪明的浏览器会先“翻翻自己的小本本”,检查本地缓存。
- 浏览器缓存 (HTTP Cache):浏览器会检查是否已经缓存了该网页的副本,并且这个副本是否仍然有效(通过
Cache-Control
和Expires
等 HTTP 头部信息判断)。如果缓存有效,浏览器可以直接从本地磁盘读取并展示页面,这个过程极快,甚至不会产生任何网络请求。这是性能优化的第一道关卡。 - HSTS 列表检查:浏览器会检查
google.com
是否在 “HTTP Strict Transport Security” (HSTS) 强制安全列表中。如果在,那么即使用户输入的是http://
, 浏览器也会强制将其转换为https
请求。
- 浏览器缓存 (HTTP Cache):浏览器会检查是否已经缓存了该网页的副本,并且这个副本是否仍然有效(通过
第二阶段:网络通信之旅(核心网络知识)
如果缓存中没有找到或者缓存已过期,浏览器就必须踏上网络之旅去获取数据。
-
DNS 查询 (Domain Name System)
- 目的:计算机在网络中通信需要知道对方的 IP 地址(例如
172.217.160.78
),而不是域名(www.google.com
)。DNS 就是“互联网的电话本”,负责将域名翻译成 IP 地址。 - 查询过程:这是一个层层查询的过程。
a. 浏览器 DNS 缓存:浏览器先看自己的缓存里有没有。
b. 操作系统 DNS 缓存:如果浏览器没有,就去看操作系统的缓存(比如 Windows 的ipconfig /displaydns
)。
c. 路由器 DNS 缓存:再查询路由器的缓存。
d. 本地 DNS 服务器 (LDNS):如果都没有,请求会被发送到你的网络服务提供商 (ISP) 的 DNS 服务器。
e. 根域名服务器 -> 顶级域名服务器 -> 权威域名服务器:如果 LDNS 也没有缓存,它会从根服务器开始,一路查询.com
的顶级域名服务器,最后找到负责google.com
的权威域名服务器,并获取到最终的 IP 地址。
- 目的:计算机在网络中通信需要知道对方的 IP 地址(例如
-
建立 TCP 连接 (Transmission Control Protocol)
- 目的:HTTP 协议是建立在可靠的 TCP 连接之上的。为了保证数据包能够按顺序、无差错地送达,客户端(浏览器)和服务器之间需要先建立一个连接。
- 三次握手 (Three-Way Handshake):这是一个经典的流程。
a. SYN: 客户端发送一个SYN
包,表示“你好,我想和你建立连接,我的序列号是 X”。
b. SYN-ACK: 服务器收到后,回复一个SYN-ACK
包,表示“好的,我收到了,我也准备好了。我的序列号是 Y,我期望你下一个包的序列号是 X+1”。
c. ACK: 客户端再发送一个ACK
包,表示“收到,连接建立成功。我下一个包的序列号是 X+1”。 - 至此,一条可靠的通信链路就建立好了。
-
TLS/SSL 握手 (对于 HTTPS)
- 目的:由于我们访问的是
https
,在 TCP 连接建立后,还需要进行一次加密握手,以确保后续通信内容(HTTP 请求和响应)不被窃听或篡改。 - 过程简化:
a. 客户端问候 (Client Hello):客户端说:“你好,我们来加密通信吧。我支持这些加密算法。”
b. 服务器响应 (Server Hello & Certificate):服务器说:“好的,我们用这个算法吧。这是我的数字证书(公钥和身份信息),你可以验证一下我的身份。”
c. 客户端验证与密钥交换:浏览器会向一个受信任的证书颁发机构 (CA) 验证该证书的真伪。验证通过后,浏览器会生成一个对称密钥,用服务器的公钥加密后发给服务器。
d. 完成握手:服务器用自己的私钥解密,得到对称密钥。从此,双方就使用这个对称密钥来加密和解密所有通信内容。
- 目的:由于我们访问的是
-
发送 HTTP 请求 (HTTP Request)
- 加密通道建立后,浏览器就可以正式发送 HTTP 请求了。一个典型的 HTTP 请求报文包含:
- 请求行 (Request Line):
GET / HTTP/1.1
(请求方法、请求路径、协议版本) - 请求头 (Headers):包含大量附加信息,如:
Host: www.google.com
(目标主机)User-Agent: ...
(浏览器信息)Accept: text/html,...
(能接收的内容类型)Cookie: ...
(用户的身份凭证)
- 请求体 (Body):对于
GET
请求,请求体为空。对于POST
请求(如提交表单),这里会包含要发送给服务器的数据。
- 请求行 (Request Line):
- 加密通道建立后,浏览器就可以正式发送 HTTP 请求了。一个典型的 HTTP 请求报文包含:
第三阶段:后端服务器处理(核心后端知识)
请求历经千山万水,终于到达了 Google 的服务器。
-
接收请求 (Request Reception)
- 请求首先可能到达的不是应用服务器,而是一个反向代理/负载均衡器 (如 Nginx, HAProxy)。
- 负载均衡器 (Load Balancer) 的作用是根据预设的策略(如轮询、最少连接数),将海量的用户请求分发到后方多台应用服务器中的一台,避免单点过载,保证服务高可用。
-
处理请求 (Request Processing)
- Web 服务器 (Web Server) (如 Nginx, Apache) 将请求转交给应用服务器。
- 应用服务器中的Web 框架 (如 Java Spring, Python Django, Node.js Express) 开始工作。
a. 路由 (Routing):框架根据请求的路径 (/
),决定调用哪个控制器 (Controller) 或处理函数来处理这个请求。
b. 中间件 (Middleware):在到达具体业务逻辑前,请求可能会经过一系列中间件,用于处理通用任务,如身份认证、日志记录、数据解析等。
c. 业务逻辑 (Business Logic):这是应用的核心。代码会执行具体的操作。对于访问谷歌首页,可能包括:
* 检查用户的登录状态(通过 Cookie)。
* 从数据库 (Database) 或缓存 (Cache) (如 Redis, Memcached) 中读取用户个性化数据。
* 调用其他内部微服务 (Microservices) 获取数据(如天气、新闻等)。
d. 数据渲染:后端将获取到的数据与一个模板 (Template) (如 HTML 模板文件) 进行结合,动态生成最终的 HTML 字符串。这个过程称为服务端渲染 (Server-Side Rendering, SSR)。
-
构建 HTTP 响应 (HTTP Response)
- 业务逻辑处理完毕后,后端会构建一个 HTTP 响应报文发回给浏览器。
- 状态码 (Status Code):
200 OK
(表示成功),404 Not Found
(未找到),500 Internal Server Error
(服务器内部错误) 等。 - 响应头 (Headers):包含重要信息,如:
Content-Type: text/html; charset=UTF-8
(告诉浏览器这是一个 HTML 文件,用 UTF-8 编码)。Set-Cookie: ...
(如果需要,服务器可以在这里给用户设置新的 Cookie)。Cache-Control: ...
(告诉浏览器如何缓存这个页面)。
- 响应体 (Body):包含生成的 HTML 文本内容。
第四阶段:浏览器渲染页面(核心前端知识)
浏览器收到服务器的响应后,就开始了将代码变为画面的神奇过程。
-
解析 HTML -> 构建 DOM 树 (Document Object Model)
- 浏览器从上到下逐行读取 HTML 响应体,并开始解析。
- 它会将 HTML 标签(如
<html>
,<body>
,<div>
) 转化为一个树形结构的对象模型,这就是 DOM。DOM 是 JavaScript 操作网页内容的接口。
-
解析 CSS -> 构建 CSSOM 树 (CSS Object Model)
- 在解析 HTML 的过程中,如果遇到
<link>
标签引入的外部 CSS 文件或<style>
标签内的样式,浏览器会异步下载并解析它们。 - CSS 解析器会把 CSS 规则转化为一个类似 DOM 的树形结构,称为 CSSOM。它描述了每个 DOM 元素应该应用什么样式。
- 在解析 HTML 的过程中,如果遇到
-
构建渲染树 (Render Tree)
- DOM 树和 CSSOM 树构建完毕后,浏览器会将它们合并,生成渲染树。
- 渲染树只包含需要被显示的节点。例如,
display: none
的元素就不会出现在渲染树中。
-
布局 (Layout / Reflow)
- 有了渲染树,浏览器知道了要画什么以及它们的样式,但还不知道它们在屏幕上的确切位置和大小。
- 布局阶段就是计算每个节点在视口 (Viewport) 内的精确几何信息(位置、尺寸)。这个过程也称为回流 (Reflow)。
-
绘制 (Painting / Rasterizing)
- 布局完成后,浏览器的主线程会将绘制指令(比如“在坐标(10,20)处画一个蓝色的矩形”)交给专门的合成器线程 (Compositor Thread)。
- 合成器会将页面的不同部分(图层)进行绘制,并最终将它们合成为一个位图,显示在屏幕上。这个过程称为绘制 (Paint) 或栅格化 (Rasterization)。
-
解析和执行 JavaScript
- 当 HTML 解析器遇到
<script>
标签时,默认会暂停 HTML 的解析,转而去下载、解析并执行 JavaScript 代码。 - 为什么会暂停? 因为 JavaScript 可能会修改 DOM 和 CSSOM(例如
document.write
或element.style.color = 'red'
)。浏览器为了避免无效的渲染工作,会等待脚本执行完毕。这也是为什么通常建议将<script>
标签放在<body>
的末尾。 - JavaScript 引擎 (如 Chrome 的 V8) 会执行代码。JS 代码可以通过 DOM API 和 CSSOM API 来动态地修改页面内容和样式,这可能会触发新的回流 (Reflow) 和重绘 (Repaint),从而更新页面视图。
- 当 HTML 解析器遇到
-
后续资源加载
- HTML 文档本身加载完成后,浏览器会发现 HTML 中还引用了其他资源,如图片 (
<img>
)、字体、视频等。浏览器会为这些资源重复上述的网络请求 -> 接收 -> (可能的)渲染过程,通常是并行下载的。
- HTML 文档本身加载完成后,浏览器会发现 HTML 中还引用了其他资源,如图片 (
总结
知识领域 | 涉及的关键技术点 |
---|---|
网络知识 | OSI/TCP/IP 模型、DNS 解析、TCP/IP 协议 (三次握手、四次挥手)、HTTP/HTTPS 协议 (请求/响应报文、方法、状态码、头部字段)、SSL/TLS 加密 (证书、握手)、网络缓存 (HTTP Cache)、CDN (内容分发网络,虽未详述但属此范畴) |
后端知识 | 服务器硬件/操作系统 (Linux)、Web 服务器/反向代理 (Nginx, Apache)、负载均衡、Web 框架 (Spring, Django, Express)、编程语言 (Java, Python, Node.js)、数据库 (MySQL, PostgreSQL, MongoDB)、缓存 (Redis, Memcached)、API 设计 (RESTful)、身份认证 (Cookie, Session, JWT)、服务端渲染 (SSR)、微服务架构 |
前端知识 | URL 规范、浏览器渲染原理 (关键渲染路径)、HTML/CSS (语义化、布局、样式)、DOM/CSSOM、JavaScript (事件循环、DOM 操作、异步编程)、浏览器缓存机制 (HTTP Cache)、性能优化 (减少回流重绘、资源懒加载)、跨域问题 (CORS)、前端框架 (React, Vue, Angular,它们在客户端进行更复杂的渲染和状态管理) |