浏览器显示网页的流程
浏览器显示 Web 页面的流程
Web 页面并不是在你向浏览器输入 URL 的瞬间就原样显示出来。
实际上,会按顺序发生 URL 解析、通过 DNS 取得 IP 地址、连接服务器、通过 HTTPS 建立安全通信通道、发送 HTTP 请求、接收服务器响应、由浏览器进行显示处理等流程。
不过,并不是每次都会从头执行所有处理。DNS 结果可能被缓存,已经连接的通信通道可能被复用,数据也可能从浏览器缓存中读取。
本文不会过度深入细节规格,而是沿着实际通信流程,整理 Web 页面显示之前发生了什么。
输入 URL 后会发生什么
例如,假设你在浏览器地址栏输入了 https[:]//example.com 这个字符串。
浏览器首先会确认输入的字符串。
它会判断这是搜索关键词,还是 Web 网站 URL;如果是 URL,就会解析访问目标。
URL 主要包含下面这些信息。
| 要素 | 例 | 含义 |
|---|---|---|
| 方案 | https | 表示用什么方式通信 |
| 主机名 | example.com | 表示想连接的网站名称 |
| 端口号 | 443 | 表示连接哪个通信窗口。也经常省略 |
| 路径 | /about | 表示请求服务器上的哪个位置 |
| 查询字符串 | ?id=10 | 向服务器传递附加信息 |
| 片段 | #section | 表示页面内的位置。通常不会发送给服务器 |
URL 是人类容易指定网站的形式。
但是,在网络上寻找通信对象时,最终需要 IP 地址。
因此,浏览器会进入从主机名查询 IP 地址的处理。
用 DNS 查询 IP 地址
浏览器仅凭 example.com 这个名称无法连接服务器。
这时使用的是 DNS。
DNS 是把域名和 IP 地址对应起来的机制。
浏览器或 OS 首先会确认自己内部是否还留有 DNS 结果。如果过去访问过同一域名,有时可以从 DNS 缓存中取得 IP 地址。
如果缓存中没有信息,就会向 DNS 解析器查询。DNS 解析器会根据需要向多个 DNS 服务器查询,寻找与目标域名对应的 IP 地址。
| 阶段 | 发生的事 | 目的 |
|---|---|---|
| 1 | 浏览器或 OS 确认缓存 | 确认是否能复用以前查询过的 IP 地址 |
| 2 | 查询 DNS 解析器 | 查询与域名对应的 IP 地址 |
| 3 | 取得 A 记录或 AAAA 记录 | 得到 IPv4 或 IPv6 的连接目标 |
| 4 | 使用 IP 地址决定连接目标 | 确定实际通信对象 |
这里取得的 IP 地址不一定固定。
即使是同一个域名,也可能因为地区、DNS 设置、负载均衡、CDN 等影响而返回不同 IP 地址。
连接服务器
知道 IP 地址后,浏览器会连接拥有该 IP 地址的服务器。
在 Web 通信中,不仅连接目标 IP 地址重要,端口号也很重要。
通常,HTTP 使用 80 号端口,HTTPS 使用 443 号端口。
| 通信方式 | 主要端口号 | 含义 |
|---|---|---|
| HTTP | 80 | 常用于未加密 Web 通信 |
| HTTPS | 443 | 常用于受 TLS 保护的 Web 通信 |
HTTP/1.1 和 HTTP/2 中,连接服务器通常使用 TCP。
另一方面,HTTP/3 使用名为 QUIC 的机制,并运行在 UDP 之上。
本文不会深入 HTTP/2 或 HTTP/3 的细节,但重要的是,浏览器会使用 IP 地址和端口号建立与服务器的通信通道。
另外,并不一定每次都会创建新连接。如果已经存在到同一服务器的连接,浏览器有时会复用既有连接。
用 HTTPS 建立安全通信通道
如果 URL 以 https 开头,浏览器会与服务器进行 HTTPS 通信。
HTTPS 是用 TLS 保护 HTTP 的通信。
TLS 主要有下面这些作用。
| 作用 | 含义 | 重要性 |
|---|---|---|
| 加密 | 让通信内容不容易被第三方读取 | 保护密码和页面内容 |
| 篡改检测 | 确认通信途中内容是否被改变 | 更容易防止中间人修改内容 |
| 对象确认 | 确认连接目标是否是预期域名的服务器 | 成为假网站和中间人攻击的对策 |
这里重要的是,HTTPS 并不只是“加密通信的机制”。
浏览器会确认服务器出示的证书,并验证该证书对访问目标域名是否有效。
通过这个确认,浏览器可以判断“自己连接的对象很可能是预期对象”。
不过,即使使用 HTTPS,也并不是所有通信相关信息都会隐藏。
例如,连接目标 IP 地址、通信发生的时间、通信量等,仅靠 HTTPS 无法完全隐藏。
另外,根据环境,与连接目标域名有关的信息也可能在通信路径上可见。
也就是说,HTTPS 对通信内容保护和对象确认非常重要,但不是完全保证匿名性的机制。
通过 HTTP/HTTPS 请求页面
建立安全通信通道后,浏览器会向服务器请求页面。
这个请求称为 HTTP 请求。
如果是 HTTPS,HTTP 请求的内容会在受到 TLS 保护的状态下发送。
例如,浏览器可能会向服务器发送下面这些信息。
| 信息 | 含义 | 补充 |
|---|---|---|
| 方法 | 想进行什么操作 | 页面取得中常用 GET |
| 路径 | 想要哪个页面或数据 | / 或 /about 等 |
| Host | 请求发往哪个域名 | 一个 IP 处理多个网站时也会使用 |
| User-Agent | 浏览器和 OS 等信息 | 用于环境判断和显示调整 |
| Accept-Language | 优先语言 | 用于判断是否显示日语页面等 |
| Referer | 从哪个页面移动而来 | 根据设置和规格,也可能不发送 |
| 网站保存的识别信息 | 用于维持登录状态和设置 |
服务器会查看这个请求,判断返回哪些数据。
即使访问同一个 URL,返回内容也可能因登录状态、Cookie、语言设置、终端种类等而变化。
服务器返回数据
服务器收到浏览器请求后,会返回 HTTP 响应。
HTTP 响应包含状态码、头、正文等。
| 要素 | 例 | 含义 |
|---|---|---|
| 状态码 | 200 | 表示请求成功、错误等 |
| 头 | Content-Type | 表示数据种类和缓存策略等 |
| 正文 | HTML 等 | 浏览器实际使用的数据主体 |
Web 页面的中心是 HTML,但仅靠 HTML 不一定完成整个页面。
许多 Web 页面会组合多个数据来显示。
| 数据 | 作用 |
|---|---|
| HTML | 表示页面结构 |
| CSS | 指定颜色、留白、布局、文字大小等外观 |
| JavaScript | 进行页面上的处理或动态变更 |
| 图片 | 显示照片、图标、图等 |
| 字体 | 调整文字外观 |
| 视频、音频 | 播放媒体内容 |
浏览器首先接收 HTML,然后追加取得 HTML 中指定的 CSS、JavaScript、图片、字体等。
因此,即使只是打开一个 Web 页面,实际上也经常发生多个 HTTP 请求。
浏览器显示到画面上
从服务器接收数据后,浏览器会把它转换成可以显示在画面上的形式。
大致会进行下面这些处理。
| 阶段 | 发生的事 |
|---|---|
| 解析 HTML | 读取页面结构 |
| 应用 CSS | 反映外观规则 |
| 计算布局 | 决定哪个元素放在哪里 |
| 绘制 | 把文字、图片、背景等显示到画面上 |
| 执行 JavaScript | 根据需要改变页面内容或动作 |
这里需要掌握的是,浏览器并不是从服务器接收已经完成的画面。
服务器返回 HTML、CSS、JavaScript、图片等材料。
浏览器会解释这些材料,并根据自己的画面大小、设置、支持功能组装页面。
因此,同一个 Web 页面也可能因 PC、智能手机、浏览器种类、画面宽度、设置而显示不同。
一个页面也会发生多次通信
Web 页面显示中重要的是,即使只打开一个页面,通信目标也不一定只有一个。
即使页面主体从 example.com 取得,图片、广告、访问分析、外部字体、外部脚本等也可能从其他域名读取。
| 通信目标 | 目的 | 例 |
|---|---|---|
| 页面主体服务器 | 取得 HTML | 正文和页面结构 |
| 图片分发服务器 | 取得图片 | 文章内图片和图标 |
| 广告服务器 | 显示广告 | 横幅广告和广告脚本 |
| 分析服务器 | 统计访问状况 | 访问分析标签 |
| 外部字体服务器 | 读取字体 | Web 字体 |
| 外部脚本服务器 | 添加功能 | 嵌入式小组件和 UI 部件 |
从使用者看来只是“打开了一个页面”,但背后可能正在与多台服务器通信。
另外,不仅是在刚打开页面时,滚动、按钮操作、搜索、表单输入、视频播放等也可能触发追加通信。
近年来的 Web 页面中,也常见先读取最低限度数据,再根据使用者操作取得追加数据的设计。
缓存有时会省略通信
显示 Web 页面时,并不一定每次都从服务器取得所有数据。
浏览器有时会临时保存过去取得的图片、CSS、JavaScript 等。
这称为缓存。
缓存有效时,浏览器可能不再从服务器重新取得同一数据,而是使用终端内保存的数据。
| 对象 | 缓存效果 |
|---|---|
| DNS 结果 | 减少重新从域名查询 IP 地址的步骤 |
| 图片 | 不必多次下载同一图片 |
| CSS | 可以复用与页面外观有关的文件 |
| JavaScript | 不必重新取得同一脚本即可使用 |
| 连接 | 有时可以复用既有通信通道 |
缓存对提高显示速度、减少通信量很重要。
不过,思考匿名性和隐私时,也需要意识到缓存、Cookie 等会留在浏览器内部的信息。
思考匿名性时的重要视角
思考匿名性时重要的是,打开 Web 页面这个行为并不是简单的一次通信。
Web 访问会涉及 DNS、IP 地址、HTTPS、Cookie、User-Agent、Referer、外部脚本、缓存等多个要素。
即使 HTTPS 保护了通信内容,连接目标 IP 地址、通信时机、通信量、浏览器发送的头、Cookie 识别、发往外部服务器的追加通信等,仍会成为其他视角的问题。
| 视角 | 确认内容 |
|---|---|
| DNS | 查询了哪个域名 |
| IP 地址 | 连接了哪个服务器 |
| HTTPS | 是否进行了通信内容加密、篡改检测、对象确认 |
| Cookie | 是否可能被识别为同一使用者 |
| User-Agent | 是否发送了浏览器和 OS 等环境信息 |
| Referer | 是否会传达从哪个页面移动而来 |
| 外部通信 | 是否也与页面主体以外的服务器通信 |
| 缓存 | 过去浏览和取得的数据是否留在终端内 |
特别重要的是,“通信内容被加密”和“别人不知道谁访问了哪里”不是同一回事。
HTTPS 对保护通信内容和确认连接对象非常重要。
但是,思考匿名性时,需要把 DNS、IP 地址、浏览器发送的信息、Cookie、外部通信等与 HTTPS 分开来看。
总结
浏览器显示 Web 页面之前,会分阶段发生多个处理。
首先,浏览器解析输入的 URL,并确认主机名。
接着,通过 DNS 查询与主机名对应的 IP 地址。
知道 IP 地址后,浏览器连接服务器。
如果是 HTTPS,会通过 TLS 进行加密、篡改检测、对象确认,并建立安全通信通道。
在此基础上,浏览器发送 HTTP 请求,服务器返回 HTML、CSS、JavaScript、图片等数据。
浏览器解析接收到的数据,并显示到画面上。
此外,在显示一个页面的过程中,也可能因为图片、广告、分析标签、外部字体、外部脚本等发生追加通信。
打开 Web 页面这一行为,比看起来由更多通信和处理构成。
理解这个流程后,不仅更容易整理 Web 的基本结构,也更容易整理思考匿名性和隐私时应该查看的要点。
相关工具
DNSLeakTest
与本文相关的外部资源。只有在符合你的处境和威胁模型时再打开。
列在这里的原因: 它可能有助于理解本文主题,但位于 Anonymity Sense 之外,使用前应先自行确认。
BrowserLeaks WebRTC
与本文相关的外部资源。只有在符合你的处境和威胁模型时再打开。
列在这里的原因: 它可能有助于理解本文主题,但位于 Anonymity Sense 之外,使用前应先自行确认。