一道熟悉的题,为什么总是答成名词串?
面试官问:“在浏览器输入一个网址,到看到页面,中间发生了什么?”
很多人的答案是“DNS、三次握手、HTTPS、HTTP、渲染”。这些词没错,但如果继续问“握手的报文怎么到服务器?”或者“第二次打开还要走一遍吗?”,那串名词就解释不了过程了。
设想电脑已经联网,现在访问 https://example.com/guide?lang=zh#intro。为了先看清主线,假设没有可用的页面缓存和连接,域名地址也需要重新解析,服务端使用 HTTP/1.1 over TLS。下面是一条教学路径,不代表浏览器每次都会完整执行所有步骤。
先把任务拆成三个问题:我要哪个资源?怎样把请求交给正确的服务?服务返回的内容怎样变成页面? 分层协议就是这些职责的分工。
网址先告诉浏览器“找谁、要什么”
浏览器会解析 URL,而不是把地址栏里的整串文字直接交给路由器。这个地址包含几个不同用途的部分:
| 部分 | 示例 | 在本次请求里的用途 |
|---|---|---|
| 方案 | https | 要求使用安全的 HTTP 通信 |
| 主机名 | example.com | 用于定位服务,也用于校验服务器身份 |
| 端口 | 未显式填写 | 通常使用 HTTPS 默认端口 443 |
| 路径与查询 | /guide?lang=zh | 指定请求的资源与查询参数 |
| 片段 | #intro | 由浏览器处理,例如定位页面中的锚点 |
因此,发给服务器的请求目标通常是 /guide?lang=zh,不包含 #intro。主机名不会在得到 IP 后就失去用途:同一地址可能承载多个站点,HTTP 仍要表达访问哪个主机,安全连接也要验证对方是否有权代表这个主机。RFC 9110 §4.2.2、§7.1规定了 HTTPS URI 与目标资源相关的语义。
浏览器还会判断能否利用已有响应或连接。若已经有可直接使用的本地响应,取页面的这一步可能无需访问服务器。这里先沿“需要联网”的分支继续。
先找到服务,再建立安全通道
主机名便于人记忆,发送 IP 数据包却需要目的 IP 地址。DNS(域名系统)负责帮助客户端获得域名对应的记录;一次解析可能得到多个候选地址。浏览器与系统的缓存、所选解析器及网络配置会影响查询路径,不应把某个固定的缓存查找顺序当成所有浏览器的规定。
拿到地址后,本例向服务端端口建立 TCP 连接。TCP 为两端应用提供可靠、有序的字节流1;连接建立时的三次握手交换控制信息,为后续传输建立状态。它解决的是传输问题,还没有证明对端有权代表 example.com。
接着,TLS(传输层安全协议)完成安全协商。浏览器验证服务器证书是否适用于目标主机,双方协商保护通信的数据所需的密钥。普通首次访问中,安全通道建立后才发送 HTTP 请求。TLS2把身份认证、机密性和完整性带入通信;“连上了某个 IP”与“连上了可信的网站”是两个判断。
查看 Mermaid 源码
sequenceDiagram
participant B as 浏览器
participant D as DNS 解析服务
participant S as HTTPS 服务端
B->>D: 查询 example.com 的地址
D-->>B: 返回候选地址
B->>S: 建立 TCP 连接(三次握手)
B->>S: TLS 协商与服务器身份验证
B->>S: 安全通道内发送 HTTP 请求
S-->>B: 安全通道内返回 HTTP 响应
B->>B: 解析 HTML,发现资源并逐步渲染图中的服务端是这条连接的终点,可能是源站,也可能是代理或 CDN 节点。DNS 查询本身也依赖网络传输;图省略了底层报文,只展示本例中的阶段先后。
到这里还有一个空缺:图里浏览器直接指向服务端,现实里电脑可能先连家里的路由器,再经过运营商网络。这些中间设备怎样把握手和数据送过去?
每个阶段的报文,都要一跳一跳走过去
电脑不会把局域网里的每个设备都当成最终服务器。它根据目的 IP 与路由表选择下一跳:目的地在本地链路上时可以直接交付;目的地在远端时,通常先交给默认网关。
在常见的 IPv4 以太网场景中,电脑需要知道下一跳的 MAC 地址,才能构造当前链路上的帧。若相关映射未知,会通过 ARP 获取。这里寻找的通常是网关的 MAC,而非远端网站的 MAC。RFC 1122 §2.3.2、§3.3.1分别讨论地址解析和发送数据报时的路由选择。
普通路由器收到帧后,取出 IP 数据包,按路由表决定从哪个接口向下一跳发送,并使用出站链路的封装。链路地址随逐跳交付而变化;在没有 NAT、隧道等处理的普通 IP 转发路径中,源与目的 IP 通常保持不变。不能由此推成“整个 IP 首部完全不变”,例如经过路由器时生存时间会变化。
域名、IP、端口与 MAC 没有互相取代,因为它们回答不同的问题:域名标识要访问的服务名称,IP 用于网络寻址,端口用于传输端点的区分,MAC 用于相应链路上的交付。知道服务器 IP,不等于知道本机这一跳该把帧交给谁。
封装:让每一层拿到它需要的信息
现在回看一次 HTTP 请求。应用决定“读取 /guide”,TCP 需要管理字节的传输,IP 需要进行网络寻址,链路需要完成本跳交付。发送端逐步加入各协议所需的信息,就是封装。
下面只表示本例的一段数据在 IPv4 以太网上的嵌套关系,不表示实际字节长度,也不意味着一个请求只产生一个帧:
以太网帧
└── IPv4 数据包
└── TCP 报文段
└── TLS 记录的数据(可能只是记录的一部分)
└── 加密后的 HTTP 字节IP 首部包含源与目的地址;TCP 首部包含端口、序列号等信息。TLS 保护 HTTP 字节,普通中间路由器无需解密出请求路径就能转发数据。
嵌套关系也有边界:TCP 是字节流,TCP 报文段的边界不等于 TLS 记录或 HTTP 消息的边界。一条请求可能分在多个报文段中,应用也可能一次读到多段请求数据。因此,“一个 HTTP 请求打包成一个 TCP 包”不是正确模型。RFC 9293 §2.2说明了字节流与 TCP 报文段的关系。
接收端按协议处理信息,把数据逐层交给上层,这是解封装。服务端 TCP 重组字节流,TLS 验证并解密记录,HTTP 实现读取消息,应用再决定返回什么。每层都可能因为检查失败而拒绝继续处理,并非机械地“剥掉首部就成功”。
四层、五层、七层,为什么都有人用?
这些数字来自不同的参考模型。面试时应先说明采用哪个模型,再解释职责。
TCP/IP 常用四层描述互联网协议族;教学中常把链路相关职责拆成数据链路层与物理层,形成五层。OSI 七层则进一步区分会话、表示等职责。下面是常见的教学对应,不能据此要求真实协议严格落入唯一一格:
| TCP/IP 四层 | 教学五层 | OSI 七层 | 本例里要回答的问题 |
|---|---|---|---|
| 应用层 | 应用层 | 应用、表示、会话 | 请求什么资源,消息如何解释 |
| 传输层 | 传输层 | 传输 | 数据交给哪个传输端点,怎样传输 |
| 网际层 | 网络层 | 网络 | 目的地址在哪,怎样跨网络转发 |
| 链路层 | 数据链路层、物理层 | 数据链路、物理 | 本跳如何交付,如何通过介质传信号 |
RFC 1122 §1.1.3使用应用、传输、网际和链路的分层描述。层次模型帮助划分职责,实际协议还可能组合多种功能;比如 TLS 放在 HTTP 与 TCP 之间,不能只因名字带“传输层”就把它等同于 TCP/IP 的传输层协议。
为什么要分层?HTTP 需要表达请求和响应,不必自行实现以太网寻址;链路可以更换为其他技术,上层仍通过约定接口使用网络。分层让职责可以分别实现和分析,但它不保证问题永远只影响一层。丢包可能最终表现成页面响应慢。
收到 HTML,为什么页面还没有完全出现?
服务端返回 HTTP 响应之后,浏览器还要解释内容。如果返回的是 HTML,浏览器会解析标签建立 DOM(文档对象模型),处理 CSS,计算布局并绘制。解析过程中发现脚本、样式、图片等资源,还可能发起更多请求3。
所以“网络响应完成”与“页面可见”“页面可交互”是不同时间点。浏览器可以边接收边解析,不必等所有资源下载结束才开始画;某些脚本执行和样式处理又会影响后续工作。服务端返回重定向时,还可能需要请求新的目标。
定位“页面慢”时,至少要分清是找地址慢、建连接慢、等服务端响应慢、下载慢,还是浏览器处理内容慢。只有最后一项慢时,反复讨论三次握手并不能解释现象。
同一个网址,流程可能缩短,也可能换一条路
第二次访问时,DNS 缓存可能省掉一次解析等待,已有连接可能省掉建立 TCP 与 TLS 的过程,可用的 HTTP 缓存可能省掉这次资源的网络获取。这些缓存分别保存地址、连接状态与响应内容,不能统称为“浏览器缓存命中”就结束分析。
另一个变化是 HTTP/3。它运行在 QUIC 上,QUIC 使用 UDP 承载,并提供安全传输能力;因此不能再照搬本例中单独建立 TCP 的步骤。UDP 自身没有 TCP 的可靠字节流服务,不代表基于 UDP 构建的 QUIC 就不可靠。RFC 9114 §2、§3说明 HTTP/3 的传输基础与连接建立。
面试中先明确协议版本与缓存条件,才能给出有意义的顺序。回答“一定三次握手”之前,需要先知道有没有新建 TCP 连接。
动手切换一次访问条件
下面只改变缓存与连接条件。先猜哪些步骤可以省去,再切换场景并点“下一步”,检查你的判断。
切换访问条件,再逐步看浏览器在做什么。
没有可用的响应、地址缓存或连接,沿完整主线走。
- 1解析 URL正在看
- 2获取地址待继续
- 3建立 TCP待继续
- 4完成 TLS待继续
- 5获取响应待继续
- 6处理页面待继续
取出主机名与请求目标;#intro 留在浏览器,不发给服务器。
教学示意:HTTP/1.1 over TLS,仅跟踪目标 HTML 的获取主线,不是抓包或耗时测量。各阶段的网络报文仍需逐跳交付;HTTP/3 使用另一条传输路径。
失败时,把症状放回这条路径
| 可见症状 | 已知边界 | 应继续找的证据 |
|---|---|---|
| 域名解析报错 | 本次地址获取没有成功,尚不能据此判断目标 HTTP 服务是否正常 | 查询结果、解析器与本地网络配置 |
| 连接超时 | 没有在预期时间内完成连接,不等于服务器应用一定宕机 | 目标 IP/端口、路由、防火墙与连接报文 |
| 证书验证失败 | 已进入安全连接相关阶段,但身份或信任检查未通过 | 证书主机名、有效期、信任链与系统时间 |
| 收到 HTTP 500 | 有 HTTP 响应方报告服务端错误 | 响应方是代理还是源站,以及相应日志 |
这些是排查方向,不是凭错误字符串就下根因结论。例如,500 可能由中间代理返回;“能收到 500”只能说明与这个响应方的通信走到了 HTTP 层,不能证明其后的源站正常。
面试时怎样把这条路线说清楚?
30—60 秒参考回答
我先按一次没有可用缓存和连接、使用 HTTP/1.1 over TLS 的 HTTPS 访问说明。浏览器解析 URL,获得目标主机、端口与请求路径;通过 DNS 得到地址,再建立 TCP 连接并完成 TLS 协商和服务器身份验证,随后发送 HTTP 请求。底层按路由选择下一跳,把数据封装成链路帧逐跳传输;服务端逐层处理并返回响应。浏览器解析 HTML、请求依赖资源、计算布局并绘制页面。实际访问可能因缓存和连接复用省掉步骤;HTTP/3 使用 QUIC,不能套用 TCP 的流程。
这段答案的作用是先确定主线。被追问某一步时,再把该步骤的输入、输出与失败情况展开。
四个追问及解析
- DNS 得到 IP 以后,域名还有用吗? 有。HTTP 要表达目标主机,TLS 验证也与目标主机有关。同一 IP 承载多个站点时,只知道地址不够。
- 为什么不直接把帧发给服务器的 MAC? MAC 用于对应链路上的交付。服务器在远端时,电脑通常先把帧交给本地网关,之后由各跳继续转发。
- HTTP 请求是否对应一个 TCP 报文段? 不对应。TCP 提供字节流;报文段边界不保留应用消息边界,一条请求可以被拆分传送。
- 收到 HTML 就意味着页面加载完成吗? 不意味着。还可能有资源请求、脚本执行、样式计算、布局与绘制;网络与渲染阶段有交错。
两个容易说错的结论
- “HTTPS 每次访问都要先三次握手。”只有需要新建 TCP 连接的相应路径才有这一过程,复用连接或 HTTP/3 会改变答案。
- “路由器收到请求,会读出 HTTP 路径再决定下一跳。”普通 IP 转发主要根据网络层信息选路;读取应用内容是代理等其他角色的能力,不能混为一谈。
现在再看“输入网址之后发生什么”,答案已经是一条有职责、有条件的路径。沿路径也会出现一个新的问题:即使数据经过相同阶段,为什么有的网站很快开始显示,却很久才下载完?这需要把等待时间与传输速度分开计算。
资料与核验日期
核验日期:2026-10-08。本文的请求场景与报文嵌套为教学示意,未声称是对 example.com 的实际抓包。
Footnotes
-
RFC 9293 §2.2:Key TCP Concepts:TCP 向应用提供可靠、有序的字节流,网络上由报文段承载。 ↩
-
RFC 9110 §4.2.2:https URI Scheme:HTTPS 对安全通信和服务器身份验证的要求;具体握手随 TLS 版本变化。 ↩
-
MDN:Populating the page: how browsers work:导航、解析与渲染的浏览器实现说明。 ↩