跳至主要内容
返回文章列表
约 12 分钟阅读

一个网址从输入到打开,到底发生了什么:网页加载与文件下载全链路

沿着 URL、DNS、TCP/QUIC、TLS、HTTP 与浏览器渲染梳理网页加载,并解释 CDN、流式下载、Range 断点续传和分层故障排查。

博客目录 →

在地址栏输入一个网址,几秒后页面出现;点击下载链接,文件逐渐落到磁盘。这些操作背后共享一条网络链路,但拿到响应后的处理方式不同。

理解这条链路,既能回答面试里的“输入网址到页面显示经历了什么”,也能帮助排查“网站打不开”“下载很慢”“文件下载到一半失败”等问题。以下以访问 https://www.baidu.com/ 为例说明一般机制;服务器侧结构是常见网站架构示例,不代表百度内部的实际实现。

一、先看完整链路

一个简化的网页访问过程是:

理解 URL、检查可用缓存
        ↓
解析域名,选择地址和连接路径
        ↓
建立或复用连接:TCP + TLS,或 QUIC
        ↓
发送 HTTP 请求,处理响应与重定向
        ↓
解析 HTML,获取 CSS、JS、图片等资源
        ↓
样式计算、布局、绘制、合成,显示并持续更新页面

这是逻辑上的顺序,不是一张必须逐项完成的清单。缓存命中可能跳过网络;连接复用可能跳过握手;资源下载、解析和渲染通常会并行或交错进行。

MDN 示意浏览器先获取 HTML,再请求脚本、样式及其他页面资源
官方文档原图:获取页面涉及多个资源请求。来源:MDN:HTTP 概述。具体请求可能命中缓存、并发发送或复用同一连接。

二、浏览器先理解网址,再决定是否需要联网

1. URL 不只是域名

一个网址可以包含协议、主机、端口、路径、查询参数和片段:

https://example.com:8443/docs?id=42#overview
  协议       主机     端口  路径  查询参数  片段

HTTP 默认端口是 80,HTTPS 默认端口是 443。显式写出 :8443 时,浏览器会使用该端口;没有写时,按协议采用默认值。直接输入 www.baidu.com 时,浏览器还会判断它是网址还是搜索词,并可能优先尝试 HTTPS。

片段 #overview 通常用于页面内部定位,不会作为 HTTP 请求目标发送给服务器。查询参数则通常属于请求目标的一部分。

2. 缓存有好几种

HTTP 缓存保存响应内容,DNS 缓存保存名称解析结果,连接池保存可复用的连接。这三者解决的问题不同。

页面也可能由 Service Worker 提供。若资源无需联网就能使用,后面的 DNS 和握手步骤可能不会发生;若缓存需要重新验证,浏览器仍会向服务器发送条件请求。

三、DNS:把名称映射到可连接的地址

DNS(Domain Name System)是分布式名称系统。浏览器可以获得 IPv4 地址记录(A)、IPv6 地址记录(AAAA),解析过程还可能涉及别名记录(CNAME)和其他记录。

系统如何查找名称,取决于浏览器、操作系统与网络配置。可能使用浏览器或系统缓存、hosts 文件、系统解析器,也可能通过浏览器配置的 DNS over HTTPS 服务查询。不能把它们的顺序写成所有设备都一致的固定流程。

递归解析器负责进一步查询

若所用的递归解析器没有可用缓存,它可以从根服务器获取顶级域线索,再向 .com 顶级域服务器查询,最后向相应权威服务器获取答案。浏览器通常不会亲自向根、顶级域和权威服务器逐个询问。

解析器经常已经缓存中间信息,因此实际查询未必走完整条链。缓存结果也有有效期,需要考虑 TTL。

DNS 与 CDN 的关系

网站可以通过 DNS、Anycast 路由、HTTP 重定向等方式把用户引导到边缘节点。CDN 不只靠“把域名换成最近服务器 IP”这一种机制,某个具体网站的解析结果也不一定就是 CDN 节点。

CDN 的“近”更接近网络可达性和性能:运营商互联、延迟、拥塞、节点负载和可用性都可能参与调度。物理位置近通常有利,但不能保证更快,也不能保证调度总能选出理论上延迟最低的节点。

四、连接怎么建立:TCP、TLS 与 QUIC

1. IP 和端口分别解决什么

IP 用于网络寻址,端口用于区分传输端点和服务。端口字段是 16 位,范围为 0~65535;0 是特殊保留值,不能当作普通服务端口随意使用。

端口常见服务说明
80HTTP常规明文 HTTP 默认端口
443HTTPSTCP 上常见 HTTP/1.1、HTTP/2;UDP 上可承载 HTTP/3
22SSH远程登录与相关传输
25SMTP常用于邮件服务器之间传递邮件
53DNS传统 DNS 可使用 UDP 或 TCP

网站也可以监听其他端口,但需要服务器、网络防火墙和客户端都允许。浏览器会限制部分端口,因此并不是任意数字都能用来提供网页服务。

2. TCP 三次握手

在典型的 HTTP/1.1 或 HTTP/2 新连接中,客户端与服务器先建立 TCP 连接:

客户端                           服务器
   ───── SYN,序号 x ────────────→
   ←──── SYN + ACK,序号 y,确认 x+1
   ───── ACK,确认 y+1 ──────────→

握手协商初始序列号与相关参数,建立连接状态。TCP 后续提供有序的字节流,通过序列号、确认、重传、流量控制和拥塞控制维持传输。它并不保留 HTTP 应用消息的边界,也不是每个网络包都对应一次单独确认。

若已有可复用连接,这次请求可以省去新的 TCP 握手。

3. HTTPS 的 TLS 握手

使用 HTTPS 时,需要建立受保护的通信。常见握手包含算法与协议协商、密钥协商,以及服务器证书验证。浏览器会检查证书链、主机名、有效期等条件,之后使用派生出的流量密钥加密应用数据。

不同 TLS 版本、会话恢复与实现细节会改变实际往返次数。TLS 保护通信内容的机密性和完整性,但不隐藏所有网络元信息:观察者仍可能看到地址、流量大小和时间等;域名是否被隐藏还取决于 DNS、ECH 等配置。

证书验证通过也不等于网站内容可信,它主要验证当前连接的身份与安全条件。

4. HTTP/3 不走 TCP

HTTP/3 使用 QUIC,QUIC 通常运行在 UDP 上并集成 TLS 1.3。可靠传输和拥塞控制由 QUIC 提供,所以“HTTPS 一定先做 TCP 三次握手,再做 TLS 握手”只适用于部分协议路径。

HTTP/2 在一条 TCP 连接上多路复用多个流,但 TCP 丢包可能阻塞同一连接上的其他流。QUIC 的流机制能减少这类跨流阻塞,仍然会受到带宽、丢包和拥塞影响。

五、HTTP:浏览器到底请求了什么

下面是便于阅读的 HTTP/1.1 请求示例,不是百度真实流量记录:

GET / HTTP/1.1
Host: www.baidu.com
User-Agent: ExampleBrowser/1.0
Accept: text/html

第一行包括方法、请求目标和版本。GET 表示获取资源,/ 表示根路径;Host 区分同一服务器托管的不同主机,Accept 表达希望接收的内容类型。符合条件时,浏览器还可能携带 Cookie,它可能参与会话管理,但不只是“登录信息”。

MDN 标注 HTTP 请求中的方法、路径、协议版本、请求头与消息体
官方文档原图:HTTP 请求结构。来源:MDN:HTTP 概述。HTTP/2 和 HTTP/3 使用帧与压缩头部,不是直接发送这段文本。

请求头后有空行,随后才是可选消息体。普通 GET 通常没有消息体;不应依赖 GET 消息体表达业务参数。

六、服务器返回什么

请求可能经过代理、CDN、WAF 和负载均衡,再到应用服务。边缘缓存命中时,它可以直接返回内容,不必每次访问源站。应用服务也可能读取缓存、查询数据库或调用其他服务。

MDN 展示客户端请求经过代理链路到达服务器并收到响应
官方文档原图:客户端与服务器之间可以存在多个中间节点。来源:MDN:HTTP 概述。

HTTP 响应包含状态信息、响应头,以及允许存在时的响应体:

状态码常见含义排查线索
200请求成功内容不一定正确,还要检查类型和正文
206返回部分内容常见于 Range 下载
301 / 302重定向检查 Location 与跳转后的域名
304缓存验证通过使用已有缓存响应,不是重新下载完整正文
401 / 403认证或访问限制检查身份、签名链接和权限
404未找到资源检查路径、部署版本和链接
500 / 502 / 504服务或网关异常结合源站、代理和超时日志判断

Content-Type 指示内容类型,Cache-Control 描述缓存策略。收到 200 也不能直接认定下载成功:登录页或错误提示可能同样以 200 返回。

七、HTML 到屏幕:解析、加载与渲染交错进行

浏览器可以在接收 HTML 的同时开始解析,构建 DOM。遇到样式表、脚本、图片和字体时,又会获取更多资源;这些资源可能来自不同域名,使用不同连接,或直接命中缓存。

CSS 参与样式计算。浏览器结合 DOM、样式与布局规则确定需要显示的内容,计算位置和尺寸,再绘制并合成到屏幕。页面不必等全部资源下载完成才第一次显示。

JavaScript 的执行方式也不一样:普通解析器插入的脚本可能阻塞 HTML 解析,defer、async 和模块脚本则有各自的加载与执行规则。后续脚本更新 DOM,字体或图片尺寸到达后,都可能引发新的样式计算和布局。

因此,把“渲染页面”写成第七步、“加载子资源”写成第八步,容易让人误以为它们完全串行。更准确的理解是:资源加载推动解析与渲染,渲染过程中又可能触发后续更新。

八、点击下载:相同的网络,不同的响应处理

点击文件链接同样会发起 HTTP 请求,必要时解析名称和建立连接,也可能复用已有连接。服务端会检查访问权限,并可能通过重定向将客户端引导到对象存储或 CDN。

302 并不是服务器把浏览器的原请求直接“转发过去”,而是向浏览器返回新的地址,浏览器再按规则请求它。签名下载 URL 常有有效期,过期后重试可能需要重新获取链接。

浏览器为什么有时展示、有时下载

处理方式受响应类型、浏览器能力、Content-Disposition、链接的 download 属性及用户设置影响。常见下载响应是:

Content-Type: application/octet-stream
Content-Disposition: attachment; filename="report.zip"

attachment 提示按附件处理。响应提供的文件名还会经过客户端安全处理,并非服务器能随意指定任意磁盘路径。

数据通常流式写入磁盘

浏览器通常边接收边缓冲并写入临时文件,而不是把整个大文件都保存在内存中。Chrome 常见 .crdownload,Firefox 常见 .part,具体行为随平台和版本变化。

传输结束后,浏览器可能完成长度检查、下载保护处理和文件重命名,但不能假定它一定计算了可信的内容哈希。TCP 的可靠字节流和 TLS 完整性保护也不等于验证“这个安装包确实是发布方的那一份”。需要更强验证时,应对照可信来源提供的 SHA-256 或数字签名。

九、Range:断点续传需要服务端支持

初次下载通常不需要 Range。恢复下载或请求分段时,客户端可以指定字节范围:

GET /large.zip HTTP/1.1
Host: example.com
Range: bytes=1048576-
If-Range: "file-version-etag"

这里表示希望从第 1,048,576 个字节偏移开始获取剩余内容。If-Range 可结合验证器判断文件版本是否仍匹配;实践中使用合适的强 ETag 等信息,避免把不同版本文件拼在一起。

支持且满足条件时,服务器可能返回:

HTTP/1.1 206 Partial Content
Content-Range: bytes 1048576-2097151/2097152
Content-Length: 1048576

服务器也可能忽略 Range 并返回完整的 200,或者返回 416 表示范围不满足。客户端必须检查状态和范围,不能直接把任何响应追加到旧文件。多个并发分段也不是所有浏览器下载的默认方式,过多并发可能触发限流。

十、怎么观察并排查这条链路

用浏览器开发者工具看页面

打开开发者工具的 Network 面板后重新加载页面,检查文档、脚本、样式和图片的请求瀑布图。重点看状态码、缓存来源、协议、重定向和 Timing;Timing 的具体展示随浏览器而异,复用连接时也可能不显示新的 DNS 或握手耗时。

“页面出来了”与“所有资源加载完成”是两件事。排查慢页面时,应区分首屏显示、脚本执行、布局抖动和后续接口响应。

用 curl 看连接与响应

在 Windows PowerShell 中显式使用 curl.exe,避免某些版本把 curl 解释成其他命令的别名:

curl.exe -v -o NUL https://www.baidu.com/

macOS 或 Linux 可以使用:

curl -v -o /dev/null https://www.baidu.com/

详细日志通常可以看到解析得到的地址、连接、TLS 信息、协商协议和请求响应头,但不会展示递归解析器查询根服务器的全过程,也不会渲染 HTML、执行网页脚本。日志可能包含 Cookie、令牌和签名 URL,分享前应清理。

观察跳转并下载文件,可以使用:

curl -L --fail --output report.zip https://example.com/report.zip

尝试从已有文件继续下载:

curl -L --fail -C - --output report.zip https://example.com/report.zip

这仍要求服务端支持续传、文件版本一致,而且链接有效。--fail 能识别部分 HTTP 错误,但无法保证一个 200 响应就是正确文件。

按出错阶段缩小范围

现象优先检查
域名解析失败DNS 配置、网络可达性、记录和缓存
连接超时或拒绝地址、路由、防火墙、端口、监听状态
TLS 验证失败证书链、域名、有效期、系统时间
重定向后 403签名过期、鉴权、请求头和跳转目标
响应等待很久边缘回源、服务处理、数据库、上游接口
文件传到一半失败链路中断、代理超时、源站、限流、磁盘空间
文件完整收到但无法使用内容类型、错误页面、版本、哈希和应用格式
HTML 快但页面慢子资源、脚本、主线程、字体与布局

一次失败可以来自多个层面。把日志时间、失败位置和请求目标对应起来,比笼统地判断“网络有问题”更容易找到原因。

参考资料

打开原图