详解:从浏览器输入URL后都发生了什么?

274 阅读7分钟

1. 用户输入 URL

用户在浏览器地址栏输入一个 URL,例如 https://www.example.com,并按下回车键。

2. 浏览器解析 URL

浏览器解析 URL,将其分解成不同的部分:

  • 协议(Scheme):如 https
  • 用户名和密码:如 username:password@(用于身份验证,现代浏览器一般不再支持直接在 URL 中输入密码)
  • 域名(Host):如 www.example.com
  • 端口号(Port):如 :443(HTTPS 的默认端口为 443,HTTP 的默认端口为 80)
  • 路径(Path):如 /
  • 查询参数(Query):如 ?query=example
  • 片段标识符(Fragment):如 #section1

3. 检查缓存

浏览器会首先检查缓存中是否有该 URL 对应的资源,如果有且未过期,则直接使用缓存中的资源进行加载,省略后续步骤。

4. DNS 解析

如果缓存中没有对应的资源,浏览器会发起 DNS 解析,找到域名对应的 IP 地址。这个过程包括:

  • 查找浏览器缓存:检查之前访问过的域名的缓存。
  • 查找操作系统缓存:检查操作系统中的 DNS 缓存。
  • 向路由器查询:路由器可能也有 DNS 缓存。
  • 向 ISP 的 DNS 服务器查询:如果上述缓存中都没有找到,则向 ISP(互联网服务提供商)的 DNS 服务器发起查询。
  • 递归查询:如果 ISP 的 DNS 服务器也没有找到,则会进行递归查询,最终找到权威 DNS 服务器,获取域名对应的 IP 地址。

DNS 递归查询过程

  1. 本地缓存:浏览器和操作系统缓存中查找记录。
  2. 路由器:向本地网络中的路由器查询。
  3. ISP 的 DNS 服务器:向互联网服务提供商的 DNS 服务器查询。
  4. 根 DNS 服务器:若 ISP 的 DNS 服务器未找到记录,向根 DNS 服务器查询。
  5. 顶级域名服务器(TLD):根服务器返回 TLD 服务器地址,如 .com.net 等。
  6. 权威 DNS 服务器:TLD 服务器返回权威 DNS 服务器地址,最终获取域名对应的 IP 地址。

5. 建立 TCP 连接

获取到 IP 地址后,浏览器与服务器之间建立 TCP 连接,通常需要三次握手过程:

  1. 客户端发送 SYN 包:请求建立连接。
  2. 服务器回应 SYN-ACK 包:表示同意建立连接。
  3. 客户端回应 ACK 包:确认连接建立。

三次握手

  1. SYN:客户端发送一个 SYN(同步序列号)包,请求建立连接。
  2. SYN-ACK:服务器收到 SYN 包,回应一个 SYN-ACK 包,表示同意建立连接并同步序列号。
  3. ACK:客户端收到 SYN-ACK 包,发送一个 ACK(确认)包,确认连接建立。

6. SSL/TLS 握手(如果是 HTTPS)

如果使用的是 HTTPS 协议,在 TCP 连接建立后,客户端和服务器还需要进行 SSL/TLS 握手,以建立安全的加密连接:

  1. ClientHello:客户端发送支持的协议版本、加密算法、压缩方法和一个随机数。
  2. ServerHello:服务器回应选择的协议版本、加密算法、压缩方法和一个随机数,并发送服务器证书。
  3. 证书验证:客户端验证服务器证书的合法性。
  4. 密钥交换:客户端生成一个 Pre-master Secret,用服务器的公钥加密并发送给服务器。
  5. 生成会话密钥:客户端和服务器根据 Pre-master Secret 生成对称加密的会话密钥。
  6. Finished:双方发送 Finished 消息,验证握手信息是否一致。

7. 发送 HTTP 请求

SSL/TLS 握手完成后,浏览器发送 HTTP 请求给服务器,通常包括以下内容:

  • 请求行:如 GET / HTTP/1.1
  • 请求头:包含用户代理、接受的语言、接受的文件类型等。
  • 请求体:POST 请求等可能包含请求体数据。

HTTP/1.1 特性

  • 持久连接:默认开启持久连接,可以复用一个 TCP 连接来发送和接收多个 HTTP 请求和响应。
  • 管道化:支持请求管道化,可以在同一个连接上同时发送多个请求,但服务器必须按照请求顺序返回响应,实际中很少使用。

HTTP/2 特性

  • 二进制分帧层:所有通信都是在一个 TCP 连接上完成,并通过二进制分帧层传输。
  • 多路复用:在一个连接上可以同时发送多个请求和响应,而不需要按照顺序一一对应。
  • 头部压缩:通过 HPACK 算法压缩头部,减少了传输的数据量。
  • 服务器推送:服务器可以主动推送资源到客户端,减少后续请求的延迟。

8. 服务器处理请求

服务器接收到请求后,处理请求:

  • 路由处理:根据请求路径找到对应的处理程序。
  • 权限验证:检查用户是否有权限访问资源。
  • 处理逻辑:执行具体的业务逻辑,可能涉及数据库查询等。
  • 生成响应:生成 HTTP 响应,包括状态码、响应头和响应体。

9. 服务器发送响应

服务器将响应数据发送回客户端,通常包括:

  • 状态行:如 HTTP/1.1 200 OK
  • 响应头:如内容类型、缓存控制等。
  • 响应体:如 HTML 文档、JSON 数据等。

10. 浏览器接收响应

浏览器接收到服务器的响应后,进行以下处理:

  • 检查状态码:如 200 表示成功,404 表示未找到,500 表示服务器错误等。
  • 解析响应头:处理缓存控制、内容类型等信息。
  • 解析响应体:根据内容类型解析响应体,例如 HTML 文档、CSS 样式表、JavaScript 文件、图像等。

11. 渲染页面

浏览器解析和渲染页面,涉及以下步骤:

解析 HTML

  • 构建 DOM 树:将 HTML 文档解析为 DOM 树。
  • 处理 CSS:解析 CSS 文件和内嵌样式,生成 CSSOM(CSS 对象模型)。
  • 构建渲染树:结合 DOM 和 CSSOM,构建渲染树。

布局(Layout)

  • 计算布局:根据渲染树计算每个元素的位置和大小。

绘制(Paint)

  • 绘制元素:将每个元素绘制到屏幕上。

处理 JavaScript

  • 下载和解析:下载和解析 JavaScript 文件。
  • 执行脚本:执行 JavaScript 脚本,可能会修改 DOM 树,触发重新布局和重绘。

12. 加载外部资源

在解析 HTML 文档过程中,如果遇到外部资源(如 CSS、JavaScript、图像等),浏览器会发送额外的请求来加载这些资源,并进行相应的处理和渲染。

13. 执行完成

浏览器完成所有资源的加载和页面的渲染,用户看到完整的网页。页面加载完成后,浏览器还会继续监听用户交互事件,并处理后续的操作。

14. 连接关闭(四次挥手)

当页面加载完成并且不再需要保持连接时,浏览器和服务器会进行 TCP 四次挥手关闭连接:

  1. 客户端发送 FIN 包:请求关闭连接。
  2. 服务器回应 ACK 包:确认关闭请求,但仍可以发送未完成的数据。
  3. 服务器发送 FIN 包:通知客户端可以关闭连接。
  4. 客户端回应 ACK 包:确认服务器的关闭请求,连接关闭。

四次挥手

  1. FIN:客户端发送一个 FIN(结束)包,请求关闭连接。
  2. ACK:服务器收到 FIN 包,回应一个 ACK 包,确认收到关闭请求。
  3. FIN:服务器发送一个 FIN 包,通知客户端可以关闭连接。
  4. ACK:客户端收到 FIN 包,发送一个 ACK 包,确认服务器的关闭请求,连接关闭。