解剖输入url到页面渲染的过程

我们在日常使用浏览器经常会在导航栏输入网页的url来访问对应的网页,于是我怀着好奇的心想去了解一下从输入了url到看到网页这个过程应该是什么样的。那么接下来就来说说过程是什么样吧。

一、浏览器

当你在浏览器中输入URL并请求访问一个网页时,浏览器会按照以下步骤进行缓存检查:

  1. 检查浏览器缓存

    • 浏览器首先会查看其本地缓存(Cache)中是否已经存储了该URL的资源。这包括HTML文档、CSS、JavaScript文件、图片等。
  2. 匹配请求

    • 如果缓存中找到了与请求URL匹配的资源,浏览器会检查该资源的有效性。有效性通常由以下几个因素决定:

      • 过期时间:缓存的资源会有一个过期时间(Expires头或Cache-Control头中的max-age)。如果当前时间超过了过期时间,则该资源被视为过期。
      • ETag或Last-Modified:浏览器可能还会使用ETag(实体标签)或Last-Modified(最后修改时间)来判断缓存内容是否仍然有效。浏览器会向服务器发送一个条件请求,询问资源是否更新。
  3. 使用缓存

    • 如果缓存资源仍然有效,浏览器将直接从缓存中读取并渲染该资源,而无需向服务器发起请求。
    • 如果资源已过期或未找到,浏览器将向服务器发送新的请求以获取最新的资源。
  4. 更新缓存

    • 在获取新资源后,浏览器会将其存储到本地缓存中,以便下次请求时使用。

二、DNS域名解析

DNS解析将人类可读的域名(如www.example.com) 转换为机器可读的IP地址 (如192.168.0.1)的过程。具体步骤分为以下几步:

  1. 浏览器缓存

    • 当在浏览器缓存没有查找到对应的IP地址,才会进行下面步骤。
  2. 操作系统缓存

    • 每当我们访问过一个域名地址不仅浏览器会缓存对应的IP地址,操作系统也会有缓存。当在浏览器缓存中没有找到的话,就会在操作系统的DNS缓存中查找。如果在这里找到了有效记录,也会直接使用。
  3. 本地DNS服务器缓存

    • 如果操作系统缓存也没有该域名的记录,那么请求会被发送到本地DNS服务器(通常是ISP提供的DNS服务器或用户手动配置的公共DNS服务器)。
    • 本地DNS服务器会先检查其自身的缓存。
    • 如果本地DNS服务器缓存中有该域名的有效记录,它会直接返回给用户的计算机。
  4. 根DNS服务器

    • 如果本地DNS服务器也没有找到该域名的记录,它会向根DNS服务器发起查询。
    • 根DNS服务器不会提供具体的IP地址,而是返回负责顶级域(TLD,如.com.org等)的权威DNS服务器的地址。
  5. 顶级域(TLD)DNS服务器

    • 本地DNS服务器接着向TLD DNS服务器发出请求。
    • TLD DNS服务器同样不会给出具体IP地址,而是指向负责次级域名(如example.com)的权威DNS服务器的地址。
  6. 权威DNS服务器

    • 最后,本地DNS服务器向该权威DNS服务器发送请求。
    • 权威DNS服务器保存有确切的IP地址信息,并将这些信息返回给本地DNS服务器。
  7. 响应传递

    • 一旦本地DNS服务器得到了正确的IP地址,它会将结果返回给用户的计算机。
    • 同时,为了提高效率,本地DNS服务器通常还会缓存这次查询的结果一段时间(基于TTL值,即生存时间)。
  8. 浏览器接收IP地址

    • 用户的计算机接收到IP地址后,就可以使用这个IP地址与目标服务器建立TCP连接,并开始请求网页内容。

以上步骤我们可以用一张图片来更清晰的解释:

三、建立TCP连接

当浏览器获取到服务器的IP地址后,下一步就是与服务器建立TCP连接。TCP(传输控制协议)是一种面向连接的、可靠的、基于字节流的传输层通信协议。为了确保数据能够可靠地传输,TCP使用三次握手来建立连接。下面是建立TCP连接的具体步骤:

  1. 发送SYN报文段

    • 客户端向服务器发送一个SYN(Synchronize Sequence Numbers)报文段。
    • 这个报文段包含一个随机的初始序列号(ISN),假设为x
    • SYN标志位被设置为1,表示这是一个连接请求。
  2. 接收SYN-ACK报文段

    • 服务器收到客户端的SYN报文段后,会回复一个SYN-ACK(Synchronize-Acknowledgment)报文段给客户端。
    • 服务器选择一个随机的初始序列号,假设为y
    • 服务器在SYN-ACK报文段中设置自己的序列号为y,并确认客户端的序列号x(通常确认号为x+1)。
    • SYN和ACK标志位都被设置为1,表示这是对连接请求的响应,并且已经准备好接收数据。
  3. 发送ACK报文段

    • 客户端收到服务器的SYN-ACK报文段后,会发送一个ACK(Acknowledgment)报文段给服务器。
    • 客户端将确认号设置为y+1,以确认收到了服务器的SYN-ACK报文段。
    • ACK标志位被设置为1,表示这是一个确认报文段。

经过这三次握手之后,TCP连接就建立了。此时,客户端和服务器都可以开始通过这个连接来发送和接收数据了。

具体细节
  • 序列号:每个TCP报文段都有一个序列号,用于标识该报文段中的第一个字节在整个会话中的位置。序列号是保证数据传输顺序的重要机制。
  • 确认号 :确认号表示期望从对方接收到的下一个字节的序列号。如果客户端发送了一个序列号为x的数据包,服务器应该回复一个确认号为x+1的确认报文段,表示它已经成功接收到了所有小于x+1的数据。
  • 窗口大小:TCP报文段中还包含一个窗口大小字段,用于指示接收方可以接收多少数据而不需要等待进一步的确认。这有助于控制数据流的速度,防止网络拥塞。
对于HTTPS

对于使用HTTPS协议的情况,在完成三次握手建立TCP连接后,还需要进行SSL/TLS握手过程,以协商加密算法、交换密钥等安全相关的信息。只有在SSL/TLS握手完成后,才能开始加密的数据传输。

这样,通过TCP三次握手,客户端和服务器就能够建立起一个可靠的全双工通信通道。一旦TCP连接建立成功,浏览器就可以通过这个连接向服务器发送HTTP/HTTPS请求,获取网页资源。

四、发送HTTP/HTTPS请求

  1. 构建请求

    • 浏览器根据用户输入的URL构造一个HTTP或HTTPS请求。
    • 请求包括请求行(如GET /index.html HTTP/1.1)、请求头(如Host: www.example.com, User-Agent, Accept等)以及可能的请求体(针对POST方法)。
  2. 发送请求

    • 通过已经建立的TCP连接,浏览器将HTTP/HTTPS请求发送给服务器。

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

  1. 服务器接收请求

    • 服务器接收到客户端的请求后,会解析请求的内容。
  2. 处理请求

    • 根据请求的方法(GET、POST等)和路径,服务器执行相应的操作,如读取文件、查询数据库、运行脚本等。
  3. 生成响应

    • 服务器处理完请求后,生成一个HTTP响应。
    • 响应包括状态码(如200 OK)、响应头(如Content-Type, Content-Length等)以及响应体(实际的网页内容或其他资源)。
  4. 发送响应

    • 服务器通过TCP连接将响应发送回客户端。

六、浏览器接收响应并渲染页面

  1. 接收响应

    • 浏览器接收到服务器的响应后,开始处理响应内容。
  2. 解析HTML文档

    • 如果响应是一个HTML文档,浏览器首先解析HTML代码,构建DOM树结构。
    • 同时,如果HTML中包含CSS样式表链接,浏览器也会并行地下载这些CSS文件,并构建CSSOM树。
  3. 加载资源

    • 在解析HTML的过程中,遇到图片、脚本、外部样式表等其他类型资源时,浏览器会再次发起网络请求以获取这些资源。
    • JavaScript脚本可能会阻塞后续内容的渲染直到它被完全执行完。
  4. 构建渲染树

    • 结合DOM树和CSSOM树的信息,浏览器创建出一个渲染树,用于确定每个元素应该如何显示。
  5. 布局计算

    • 根据渲染树中的信息,浏览器计算出每个节点的确切位置和大小,即所谓的"布局"阶段。
  6. 绘制

    • 最后一步是将布局后的各个节点转换为屏幕上的实际像素点,也就是我们看到的网页内容。
  7. 合成

    • 现代浏览器使用多层技术来优化性能,在某些情况下,不同部分可能是分层独立绘制然后合成到一起显示给用户的。
  8. 更新缓存

    • 在获取新资源后,浏览器会将其存储到本地缓存中,以便下次请求时使用。

关闭TCP连接

四次挥手

在某些情况下,特别是当不再需要保持连接时,客户端和服务器会通过四次挥手来关闭TCP连接。以下是四次挥手的具体步骤:

  1. 发送FIN报文段

    • 当客户端或服务器决定关闭连接时,它会向对方发送一个FIN(Finish)报文段。
    • 这个报文段表示发送方已经没有更多的数据要发送了,但仍然可以接收数据。
  2. 接收FIN-ACK报文段

    • 对方收到FIN报文段后,会回复一个ACK(Acknowledgment)报文段,确认收到了FIN报文段。
    • ACK标志位被设置为1,并且确认号设置为接收到的FIN报文段中的序列号加1。
  3. 发送FIN报文段

    • 如果对方也有数据需要发送,它会在所有数据发送完毕后,也发送一个FIN报文段给发起关闭的一方。
    • 这个FIN报文段同样表示发送方已经没有更多的数据要发送了。
  4. 接收FIN-ACK报文段

    • 发起关闭的一方收到对方的FIN报文段后,会回复一个ACK报文段,确认收到了FIN报文段。
    • 这样,双方都确认了对方没有更多的数据要发送,TCP连接就可以安全地关闭了。

总结

将所有步骤总结为一张图片:

相关推荐
梦境之冢11 小时前
axios 常见的content-type、responseType有哪些?
前端·javascript·http
DashVector11 小时前
如何通过HTTP API检索Doc
数据库·人工智能·http·阿里云·数据库开发·向量检索
哈利巴多先生11 小时前
HTTP,续~
网络·网络协议·http
白了个白i11 小时前
http的访问过程或者访问页面会发生什么
网络·网络协议·http
qq_3720068612 小时前
浏览器http缓存问题
网络协议·http·缓存
唐 城1 天前
curl 放弃对 Hyper Rust HTTP 后端的支持
开发语言·http·rust
DevilHeart灬1 天前
使用Grafana中按钮插件实现收发HTTP请求
http·grafana
总是学不会.1 天前
第五篇:前后端如何“扯皮”——HTTP 在开发中的应用
java·网络·网络协议·http·开发
火狮1 天前
鸿蒙Next API 12开发,使用@ohos/axios进行HTTP请求
http·华为·harmonyos
m0_748238271 天前
WebClient HTTP 请求问题处理模板(泛型响应、忽略 SSL 证书等)
网络协议·http·ssl