从输入 URL 到页面展示到底发生了什么

作者: jie 分类: 前端 发布时间: 2023-07-05 11:48

本文的目的是通过输入 url 之后发生的事情来做知识的总结和扩展。所以文章可能会比较发散。

总结的过程大致如下:

1、URL 解析

当我们开始在浏览器地址栏中输入网址的时候,浏览器其实就已经在智能的匹配可能的 url 了,它会从历史记录、书签等地方找到已经输入的字符串可能对应的 url,然后给出智能提示,让你可以不全 url 地址。对于 Chrome 浏览器来说,它甚至会直接从缓存中把网页展示出来,也就是说,你还没有按下 Enter 键,页面就出来了。

当我们输入完成 URL 并按下 Enter 键后,浏览器首先要解析输入的 URL,确定要访问的是哪个网站。该过程包括协议解析、主机名解析、端口解析、路径解析等。

比如,对于 URL“https://www.hi-ruofei.com/archives/161.html”来说,协议是“https”,主机名是”www.hi-ruofei.com”,端口是 443,路径是”/archives/161.html”。

2、DNS 查询

浏览器会将主机名(www.hi-ruofei.com)解析成 IP 地址,如果本地已经缓存了 DNS 记录,这一过程会很快。如果没有,那么请求就会发送到配置的 DNS 服务器,通常就是你的网络服务提供商处,比如中国电信、中国移动。之后 DNS 服务器会查找相应的记录并返回给浏览器。如果 DNS 服务器没有缓存要查询的记录,DNS 服务器还要向 DNS 根服务器查询。

3、建立 TCP 连接

一旦浏览器获取了服务器的 IP 地址,它就会向服务器发起 TCP 连接。这个过程通常被称为“三次握手”。这个过程的目的是为了在浏览器和服务器之间建立一个可靠的连接,以便于数据的传输。

4、发送 HTTP 请求

浏览器通过 TCP 连接向服务器发送 HTTP 请求。这个请求包括请求行(例如 GET /index.html HTTP/1.1)、请求头(例如 User-Agent, Accept 等)和请求体(如果是 POST 请求的话)。

5、服务器处理请求并返回 HTTP 响应

服务器接收到请求后,会根据请求的 URL 和方法,处理请求并生成响应,然后通过 TCP 连接返回给浏览器。这个响应包括响应状态行(例如 HTTP/1.1 200 OK)、响应头(例如 Content-Type, Content-Length 等)和响应体(即网页的 HTML 内容)。

6、浏览器解析 HTML

浏览器接收到 HTTP 响应后,会开始解析 HTML,构建 DOM 树。在这个过程中,如果遇到 CSS、JavaScript、图片等资源的链接,浏览器会再次发起 HTTP 请求获取这些资源。

7、浏览器渲染页面

浏览器在构建 DOM 树的同时,会构建 CSSOM 树(CSS Object Model)。然后浏览器会将 DOM 树和 CSSOM 树合并成一个渲染树(Render Tree),并根据这个渲染树来计算每个节点的布局(Layout),然后绘制(Paint)出页面。如果遇到 JavaScript,浏览器会执行 JavaScript 代码,可能会修改 DOM 树和 CSSOM 树,这可能会导致重新布局和绘制。

8、关闭 TCP 连接

  1. 最后,浏览器会关闭 TCP 连接,进行四次挥手。这个过程是为了优雅地关闭连接,确保所有的数据都已经被接收。

这就是从输入 URL 到页面展示的整个过程,我们结合这个过程来扩展一些知识点。

1. 什么是 DNS?

DNS,全称为Domain Name System(域名系统),是互联网的一项核心服务。它作为将域名和 IP 地址相互映射的一个分布式数据库,能够使人更方便地访问互联网,而不需要记住能够被机器直接读取的 IP 数串。

在互联网上,每个设备都有一个唯一的 IP 地址,就像每个人都有一个唯一的电话号码一样。IP 地址由一串数字组成,比如:192.168.1.1,这对我们来说不容易记忆。因此,我们使用域名来代替 IP 地址。我们可以把 DNS 看做是一个电话本,比如要找 hi-ruofei.com 这个域名,翻翻电话本,就知道它的 ip 是 167.23.10.2。

2. TCP 三次握手

  1. SYN:客户端发送一个带有 SYN(Synchronize Sequence Numbers)标志的数据包给服务器,以请求建立连接。这个数据包还包含一个随机的序列号 A。假设你(客户端)打电话给一个朋友(服务器),这次握手就表示你拨打朋友的电话号码(发送 SYN 请求)。
  2. SYN-ACK:服务器接收到客户端的 SYN 请求后,会发送一个带有 SYN 和 ACK (Acknowledgement)标志的数据包给客户端。这个数据包包含一个自己的随机序列号 B,以及对客户端序列号 A 的确认(即 A+1)。可以这样理解——你的朋友接到电话后说:“你好,我听到你了。”(发送 SYN-ACK 响应),这表示他的电话是通的,他能听到你的声音。
  3. ACK:客户端接收到服务器的 SYN-ACK 数据包后,会发送一个带有 ACK 标志的数据包给服务器,确认服务器的序列号 B(即 B+1)。至此,一个TCP连接就建立起来了。当你听到朋友的回应后,你说:“我也听到你了。”(发送 ACK 确认),这表示你的电话也是通的,你也能听到他的声音。

为什么要这样设计呢?主要有两点:

  1. 可靠性:通过三次握手,双方都能确认对方的发送和接收能力,确保数据能够正确无误地在两者之间传输。
  2. 防止旧的连接请求报文突然出现在网络中:如果不使用三次握手,那么只要服务器接收到请求,就直接建立连接。但是,如果这个请求是一个旧的请求,比如说是因为网络延迟,那么服务器就会错误地建立一个不存在的连接,浪费资源。通过三次握手,可以防止这种情况发生,因为客户端会在最后一次握手中确认是否真的要建立连接。

3. TCP 四次挥手

  1. FIN:当客户端决定关闭连接时,它会发送一个带有 FIN(Finish)标志的数据包给服务器,表示客户端已经没有数据要发送了。假设你(客户端)正在和一个朋友(服务器)通电话,这次挥手就表示你告诉朋友你要挂电话了(发送 FIN 请求)。
  2. ACK:服务器接收到客户端的 FIN 数据包后,会发送一个带有 ACK(Acknowledgement)标志的数据包给客户端,表示服务器已经接收到了客户端的关闭请求,但可能还有数据需要处理和发送。你的朋友听到你要挂电话,他说:“我知道了,但我还有几句话要说。”(发送 ACK 响应),这表示他已经知道你要挂电话,但他还有一些话要说。
  3. FIN:当服务器处理完所有数据并准备好关闭连接时,它会发送一个带有FIN标志的数据包给客户端。你的朋友说完他的话后,他说:“我说完了,我们可以挂电话了。”(发送 FIN 请求)。
  4. ACK:客户端接收到服务器的 FIN 数据包后,会发送一个带有 ACK 标志的数据包给服务器,表示客户端已经接收到了服务器的关闭请求,并确认服务器可以关闭连接。至此,TCP连接就被成功关闭了。你听到朋友的话后,你说:“好的,我们挂电话吧。”(发送 ACK 确认),这表示你已经知道朋友已经说完话,同意挂电话。

为什么要这样设计呢?而且,为什么建立连接是三次握手,而关闭连接却是四次挥手呢?

首先,这样设计的原因主要是因为 TCP 是一个全双工协议,这意味着客户端和服务器可以同时发送和接收数据。因此,关闭连接时,需要双方都确认对方已经没有数据要发送,这就需要四次挥手。

在建立连接时,只需要确认双方的发送和接收能力,因此只需要三次握手即可;而在关闭连接时,除了确认双方的发送和接收能力,还需要确认双方都已经没有数据要发送,这就需要额外的一次交互,也就是四次挥手。

从输入 URL 到页面展示其实还涉及到很多非常复杂的技术和协议,这里只介绍了 DNS 的概念和 TCP 三次握手以及 TCP 的四次挥手

发表回复