浏览器输入URL后发生了什么

244 阅读12分钟

当你在浏览器中输入一个 URL 后,发生了以下主要步骤:

URL 解析

浏览器首先解析输入的 URL。这包括解析协议(如 HTTP、HTTPS)、主机名、端口号、路径以及查询参数等。解析后,浏览器就知道了要访问的服务器和资源路径。

协议解析

浏览器首先解析 URL 中的协议部分。例如,如果 URL 是以 "http://" 或 "https://" 开头,浏览器就知道使用的是 HTTP 或 HTTPS 协议。

主机名解析

解析 URL 中的主机名(域名),这是指向服务器的地址。如果 URL 中包含了主机名,浏览器就需要将主机名转换为 IP 地址,这一步称为 DNS 解析。如果主机名是 IP 地址形式,则 跳过 DNS 解析。

端口号解析

解析 URL 中的端口号。端口号是用于区分同一台服务器上不同服务的数字。如果 URL 中没有明确指定端口号,浏览器将使用默认的端口号(HTTP 默认为 80,HTTPS 默认为 443)。

路径解析

解析 URL 中的路径部分。路径指明了服务器上所请求资源的具体位置。如果路径为空,服务器将返回默认资源(通常是网站的首页)。

查询参数解析

解析 URL 中的查询参数。查询参数是附加在 URL 路径后面的键值对,用于向服务器传递额外的信息。查询参数通常以 ? 开头,不同参数之间用 & 分隔。

哈希部分解析

解析 URL 中的哈希部分。哈希部分通常以 # 开头,用于标识页面中的特定位置。在前端开发中,哈希部分还可以用于实现单页面应用(SPA)中的路由。

其他信息解析

解析其他可能的信息,如用户名和密码。URL 中的用户名和密码信息通常被废弃,因为它们可能涉及到安全性问题,而现代的认证方式更多地使用其他方式,如 cookie 或 token。 总的来说,URL 解析的目的是将用户输入的 URL 转换为浏览器能够理解的信息,以便浏览器能够向正确的服务器发起请求并获取相应的资源。这些解析过程帮助浏览器确定请求的协议、目标服务器、端口号、路径等信息,从而建立起与服务器的通信。

DNS 解析

DNS(Domain Name System) 解析是将人类可读的域名转换为计算机可理解的 IP 地址的过程。浏览器通过域名系统(DNS)将主机名转换为服务器的 IP 地址。这是通过向 DNS 服务器发送查询请求来完成的。如果 DNS 缓存中存在相应的记录,将直接返回 IP 地址;否则,会发起 DNS 查询。下面是 DNS 解析的详细步骤:

浏览器缓存检查

浏览器首先检查自己的缓存,看是否已经解析过相同的域名。如果已经有缓存,就可以跳过后续的 DNS 解析步骤,直接使用缓存中的 IP 地址。

操作系统缓存检查

如果浏览器缓存中没有找到相应的域名信息,浏览器将检查操作系统的缓存。操作系统也会缓存域名和对应的 IP 地址,如果找到了,就返回给浏览器。

本地 DNS 解析器查询

如果在浏览器和操作系统的缓存中都没有找到相应的域名信息,浏览器会向本地计算机上的 DNS 解析器发起查询请求。这通常是由用户的 Internet Service Provider(ISP,互联网服务提供商)提供的。

递归查询

如果本地 DNS 解析器缓存中没有找到域名信息,它将发起一个递归查询。这时,本地 DNS 解析器会向根域名服务器发起请求,询问它要查询的域名的顶级域名服务器(TLD,Top-Level Domain)的 IP 地址。

TLD 域名服务器查询

根域名服务器返回给本地 DNS 解析器一个 TLD 域名服务器的 IP 地址。TLD 域名服务器通常负责管理特定顶级域名(如 .com、.net、.org)。

权威域名服务器查询

本地 DNS 解析器向 TLD 域名服务器发起请求,询问目标域名的权威域名服务器的 IP 地址。权威域名服务器是负责管理特定域名的服务器,它保存着该域名下所有主机记录(包括 IP 地址)的信息。

目标域名服务器查询

本地 DNS 解析器向权威域名服务器发起请求,询问目标域名的 IP 地址。权威域名服务器返回目标域名对应的 IP 地址给本地 DNS 解析器。

本地 DNS 解析器缓存更新

本地 DNS 解析器将获取到的 IP 地址存储在缓存中,以备将来使用。这样,下次浏览器再次请求相同的域名时,就可以直接从本地 DNS 解析器的缓存中获取,而无需再次进行完整的 DNS 解析流程。

返回 IP 地址给浏览器

本地 DNS 解析器将获取到的 IP 地址返回给浏览器。浏览器将使用这个 IP 地址来建立与目标服务器的连接,并请求相应的资源。整个 DNS 解析的过程是一个层层递归的查询过程,最终找到目标域名对应的 IP 地址。这使得 DNS 解析系统能够高效地管理和维护大量的域名和 IP 地址映射关系。

建立 TCP 连接

浏览器通过传输控制协议(TCP)与服务器建立连接。建立 TCP 连接是通过三次握手(Three-Way Handshake)的过程完成的。TCP(Transmission Control Protocol)是一种面向连接的协议,确保数据可靠地传输。

第一次握手 - SYN(同步)

  • 客户端首先向服务器发送一个 TCP 报文,其中包含一个标志位 SYN(同步)。这表示客户端想要建立连接。同时,客户端选择一个初始的序列号(SeqNum),用于后续数据传输的顺序标识。

第二次握手 - SYN + ACK

  • 服务器收到客户端的 SYN 报文后,确认收到了客户端的请求。服务器向客户端发送一个带有 SYN 和 ACK 标志位的 TCP 报文。服务器也选择一个自己的初始序列号(SeqNum),用于回应客户端的数据。

第三次握手 - ACK

  • 客户端收到服务器的 SYN + ACK 报文后,向服务器发送一个带有 ACK 标志位的 TCP 报文,表示连接建立成功。这个 ACK 报文中,客户端将确认号(AckNum)设置为服务器的序列号加1,表示客户端已经准备好接收数据了。

完成了这三次握手之后,TCP 连接就建立起来了。双方可以开始在这个连接上进行数据的传输。值得注意的是,三次握手的目的是确保双方都能够正确地接收对方的数据。如果只有两次握手,可能会导致一些异常情况,比如服务器收到了客户端的连接请求,但客户端并没有收到服务器的确认,这时服务器就会一直等待,而客户端可能认为连接已经建立,导致数据传输的问题。

关闭连接时,双方需要通过四次挥手(Four-Way Handshake)来完成连接的终止过程。这确保了双方在关闭连接时能够彼此通知对方,防止数据的不完整传输。以下是四次挥手的具体步骤:

第一次挥手 - 主动关闭方发送 FIN

  • 主动关闭方(通常是客户端)向被动关闭方(通常是服务器)发送一个带有 FIN(Finish)标志位的 TCP 报文,表示主动关闭方已经完成数据的发送,希望开始关闭连接。

第二次挥手 - 被动关闭方确认收到 FIN

  • 被动关闭方收到主动关闭方的 FIN 报文后,向主动关闭方发送一个 ACK 报文,确认收到了 FIN 报文。此时,被动关闭方进入半关闭状态,表示它不再向主动关闭方发送数据,但仍然可以接收来自主动关闭方的数据。

第三次挥手 - 被动关闭方发送 FIN

  • 被动关闭方在完成自己的数据发送后,也向主动关闭方发送一个带有 FIN 标志位的 TCP 报文,表示被动关闭方已经完成数据的发送,希望开始关闭连接。

第四次挥手 - 主动关闭方确认收到 FIN

  • 主动关闭方收到被动关闭方的 FIN 报文后,向被动关闭方发送一个 ACK 报文,确认收到了 FIN 报文。此时,主动关闭方进入半关闭状态。被动关闭方收到 ACK 后,就知道可以安全地关闭连接了。

完成了这四次挥手之后,TCP 连接就彻底关闭了。在这个过程中,双方都有机会告知对方自己已经完成数据的发送,并且确保对方收到了这个通知,从而避免数据的丢失和不完整传输。需要注意的是,TCP 连接的关闭过程是有序的,即在每一步都需要等待对方的确认。这确保了数据的可靠传输,使双方都有足够的时间来处理未完成的数据传输和关闭连接。

发起 HTTP 请求

浏览器通过 TCP 连接向服务器发起一个 HTTP 请求。发起 HTTP 请求是指浏览器或其他客户端向服务器请求获取特定资源的过程。HTTP 请求遵循客户端-服务器模型,其中客户端(例如浏览器)向服务器发出请求,并等待服务器的响应,该请求包含了请求的方法(GET、POST 等)、路径、协议版本、请求头等信息。

构建请求行:

HTTP 请求的第一部分是请求行,包含了请求的方法、目标资源的路径和协议版本。常见的 HTTP 方法有 GET、POST、PUT、DELETE 等。示例如下

Copy code
GET /path/to/resource HTTP/1.1

构建请求头

请求头包含了关于请求的附加信息,比如客户端的信息、接受的数据类型、授权信息等。一些常见的请求头包括:

Copy code
Host: example.com
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.0.0 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8

构建请求体(对于 POST、PUT 等方法)

对于某些请求方法,如 POST 或 PUT,请求体可能包含要发送给服务器的数据。数据的格式通常由请求头中的 Content-Type 字段指定。

Copy code
Content-Type: application/json
{"username": "john_doe", "password": "password123"}

建立 TCP 连接

在发送 HTTP 请求之前,浏览器需要与服务器建立 TCP 连接。这通常是通过域名解析和三次握手的过程来完成的,前面提到的建立 TCP 连接的步骤。

发起请求

将构建好的请求行、请求头、请求体等信息封装成一个 HTTP 请求报文,然后通过建立好的 TCP 连接向服务器发送请求。

Copy code
GET /path/to/resource HTTP/1.1
Host: example.com
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.0.0 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8

等待服务器响应

一旦请求被发送,客户端就会等待服务器的响应。服务器会解析请求并根据请求的内容返回相应的资源或执行相应的操作。

接收响应

服务器通过 TCP 连接将响应报文发送回客户端。响应报文包含了响应的状态码、响应头和响应体。

Copy code
HTTP/1.1 200 OK
Content-Type: text/html; charset=utf-8
Content-Length: 1234

处理响应

客户端接收到服务器的响应后,会根据状态码和响应体等信息处理响应。如果状态码是 200,表示请求成功,客户端可能会解析响应体并将其显示在用户界面上。如果状态码是其他值,客户端可能会采取相应的错误处理措施。

以上步骤描述了简单的 HTTP 请求的过程。实际上,HTTP 协议支持更多的特性,如缓存控制、重定向、Cookie 管理等,这些会涉及到更多的请求头和响应头的处理。

服务器处理请求

服务器接收到浏览器发来的请求后,根据请求的路径和其他信息,执行相应的处理逻辑。这可能涉及到查询数据库、处理业务逻辑、读取文件等。

服务器返回响应

服务器处理完请求后,将相应的数据以 HTTP 响应的形式返回给浏览器。响应包括响应状态码、响应头和响应体等。

浏览器渲染

浏览器接收到服务器返回的响应后,开始解析 HTML、CSS 和 JavaScript。渲染引擎根据 HTML 构建文档对象模型(DOM),根据 CSS 构建样式对象模型(CSSOM),然后将它们结合起来形成渲染树。JavaScript 可能会修改 DOM 和 CSSOM,触发重新布局和绘制。

显示页面

浏览器将渲染后的页面显示给用户。这包括在屏幕上呈现文档、加载图像和执行 JavaScript。

这是一个简要的描述,实际上还涉及到更多的细节和优化。这个过程中使用的协议可能是 HTTPS 而不是 HTTP,还可能涉及到缓存、cookie、跨域请求等其他因素。总的来说,输入 URL 后,浏览器和服务器之间经历了一系列的通信和处理过程,最终呈现出用户可见的网页。。