从输入 URL 到页面展示在浏览器中,发生了什么?
从输入 URL 到页面展示在浏览器中,中间都经历了啥?
1️⃣ URL 地址解析
首先我们拿到输入的 URL,对其进行解析,例如:
URL 解析,主要是解析出下面这些信息:
【传输协议】:负责客户端和服务器端之间信息的传输(可以理解为快递小哥)。
传输协议有以下几类:
http
:即 HyperText Transfer Protocol,超文本传输协议。除传输文本内容外,还可传输图片和音视频等。https
:即 Hypertext Transfer Protocol Secure,HTTP+SSL,更安全的传输协议,经过加密处理。ftp
:即 File Transfer Protocol,文件传输协议,主要用于往服务器上上传内容和下载内容。
【域名】:用于标识服务器在网络中的位置。
【端口号】:
端口号的作用是区分相同服务器上部署的不同项目,取值范围在 0 ~ 65535 之间。浏览器有默认端口号机制,我们在地址栏中输入 URL 地址,如果没有写端口号,则浏览器会根据当前的传输协议,自动把端口号加上!
- http -> 80
- https -> 443
- ftp -> 21
【请求资源的路径名称】。
【问号传参信息】。
【哈希值】:
- Hash 值。
❗这里要注意 URL、URI、URN 的区别:
- URL:统一资源定位符,用于定位资源
- URI:统一资源标识符,用于标识资源
- URN:统一资源名称,用于标识资源
它们之间的关系如下图所示:
2️⃣ 浏览器缓存检查
在输入 URL 到页面展示的过程中,我们需要加载许多资源,例如:
- 一些静态资源,例如:html、css、js、图片、音频、视频…
- 通过
ajax
/fetch
获取的数据 - …
浏览器在加载这些资源时,会先检查浏览器缓存中是否存在这些资源,如果存在,则直接从缓存中获取资源,否则,就向服务器发送请求获取资源。
当然对于不同类型的资源,一般会有不同的缓存策略,例如:
- 对于静态资源,一般使用浏览器自身的 强缓存和协商缓存 机制;
- 对于
ajax
/fetch
获取的数据,一般使用本地存储,例如:localStorage
、sessionStorage
、indexedDB
等,当然,也可以使用 vuex / redux 来进行缓存。
3️⃣ DNS 解析
DNS 解析,即域名解析,也就是将我们前面解析 URL 得到的域名解析为 IP 地址(主机地址)。
DNS 解析步骤:
比如对于域名 www.google.com
网址:
- 首先在浏览器的 DNS 解析缓存中查找,找不到就去本地 Host 文件中查找,接下来是本地 DNS 解析器缓存、本地 DNS 服务器。
- 如果本地没有找到缓存,就会去根域名服务器查找,没有再去顶级域名服务器、权威域名服务器查找,如此的类推下去,直到找到 IP 地址,然后把它记录在本地,供下次使用。
需要注意的是,每一次 DNS 解析的时间,大概在 20 ~ 120 毫秒左右。
所以,简单地说,DNS 的时间开销多少,会影响网页的加载速度快慢!
那么如何优化 DNS 解析呢?
- 把所有的资源部署在相同服务器的相同服务下,从而减少解析次数;
- DNS 负载均衡,比如访问
www.baidu.com
的时候,每次响应的并非是同一个服务器(IP地址不同),一般大公司都有成百上千台服务器来支撑访问。DNS可以返回一个合适的机器的IP给用户,例如可以根据每台机器的负载量,该机器离用户地理位置的距离等等,这种过程就是 DNS 负载均衡; - 在 DNS 解析次数增加的情况下,我们可以基于
dns-prefetch
即 DNS 预解析,来提高网站的加载速度;
4️⃣ 建立 TCP 连接(TCP 三次握手)
这一步的目的是在获取到服务器 IP (主机地址)后,与其建立连接:
为了保证传输通道的稳定性,客户端和服务器都需要知道以下 4 条信息:
客户端可以正常发信息
服务器可以正常接收信息
服务器可以正常发信息
客户端可以正常接收信息
而三次握手的过程,实际上就是客户端和服务器之间互相确认这 4 条信息的过程:
第一次握手:
客户端
发送一个信息,服务器
接收请求:此时,对于:
客户端
:知道了客户端可以正常发信息
;服务器
:知道了客户端可以正常发信息
、服务器可以正常接收信息
。
第二次握手:
服务器
发送一个信息,客户端
接收请求:此时,对于:
客户端
:服务器可以正常接收信息
、服务器可以正常发信息
以及客户端可以正常接收信息
,即客户端
的 4 条信息都确认了;服务器
:知道了服务器可以正常发信息
。
第三次握手:
客户端
发送一个信息,服务器
接收请求:此时,
服务器
知道了客户端可以正常接收信息
,那么服务器
的 4 条信息也都得到了确认。
这样,客户端
和 服务器
之间就建立了稳定的连接通道,可以进行数据传输了。
所以,这里也可以看出三次握手为什么不用两次,或者四次,因为 TCP 作为一种可靠传输控制协议,其核心思想是既要保证数据可靠传输,又要提高传输的效率!
5️⃣ 客户端和服务器之间的数据通信
这一步简单来说就是客户端和服务器之间进行数据通信,也就是我们常说的 HTTP 请求和响应。
6️⃣ TCP 四次挥手
这一步的目的在于把建立好的传输通道释放掉。
这里以客户端主动关闭连接为例,来说明四次挥手的过程:
第一次挥手
客户端发送一个 FIN
,用来关闭客户端到服务器的数据传送,也就是客户端告诉服务器:我已经不会再给你发数据了(当然,在 FIN
包之前发送出去的数据,如果没有收到对应的 ACK
确认报文,客户端依然会重发这些数据),但是,此时客户端还可以接受数据。
其中,FIN = 1,其序列号为 Seq = u(等于前面已经传送过来的数据的最后一个字节的序号加 1),此时,客户端进入 FIN-WAIT-1(终止等待 1)状态。
第二次挥手
服务器收到 FIN
包后,发送一个 ACK
给对方并且带上自己的序列号 Seq
,确认序号为收到序号 + 1(与 SYN
相同,一个 FIN
占用一个序号)。此时,服务端就进入了 CLOSE-WAIT
(关闭等待)状态。TCP 服务器通知高层的应用进程,客户端向服务器的方向就释放了,这时候处于半关闭状态,即客户端已经没有数据要发送了,但是服务器若发送数据,客户端依然要接受。这个状态还要持续一段时间,也就是整个 CLOSE-WAIT
状态持续的时间。
此时,客户端就进入 FIN-WAIT-2
(终止等待 2)状态,等待服务器发送连接释放报文(在这之前还需要接受服务器发送的最后的数据)。
第三次挥手
服务器发送一个 FIN
,用来关闭服务器到客户端的数据传送,也就是告诉客户端,我的数据也发送完了,不会再给你发数据了。由于在半关闭状态,服务器很可能又发送了一些数据,假定此时的序列号为 Seq = w
,此时,服务器就进入了 LAST-ACK
(最后确认)状态,等待客户端的确认。
第四次挥手
主动关闭方收到 FIN
后,发送一个 ACK
给被动关闭方,确认序号为收到序号 + 1,此时,客户端就进入了 TIME-WAIT
(时间等待)状态。注意此时 TCP 连接还没有释放,必须经过 2 * MSL(最长报文段寿命)的时间后,当客户端撤销相应的 TCP 后,才进入 CLOSED
状态。
服务器只要收到了客户端发出的确认,立即进入 CLOSED
状态。同样,撤销 TCP
后,就结束了这次的 TCP
连接。可以看到,服务器结束 TCP
连接的时间要比客户端早一些。
至此,完成四次挥手。
7️⃣ 浏览器渲染
接下来,就是浏览器把服务器返回的信息(包括 html / css / js / 图片 / 数据 等)进行渲染,最后绘制出对应的页面。
这一部分的内容可见 浏览器渲染原理
8️⃣ 页面展示
最后,浏览器把渲染好的页面展示给用户。
- 标题: 从输入 URL 到页面展示在浏览器中,发生了什么?
- 作者: 6dianbiqi
- 创建于 : 2025-02-18 13:14:38
- 更新于 : 2025-02-18 14:24:23
- 链接: https://6dianbiqi.com/2025/02/18/从输入 URL 到页面展示在浏览器中,发生了什么?/
- 版权声明: 本文章采用 CC BY-NC-SA 4.0 进行许可。