URL是怎么渲染成一个页面的

421 阅读10分钟

1.DNS解析

概念:

DNS解析(Domain Name System Resolution)是将人类可读的域名(如 www.example.com)转换为机器可读的 IP 地址(如 93.184.216.34)的过程。

步骤:

步骤 1:检查浏览器缓存
  • 浏览器会首先检查自己的缓存,看是否已经解析过该域名。
  • 如果有缓存且未过期,直接使用缓存中的 IP 地址,解析过程结束。
步骤 2:检查操作系统缓存
  • 如果浏览器缓存中没有,浏览器会检查操作系统的 DNS 缓存(如 Windows 的 hosts 文件或 Linux 的 /etc/hosts 文件)。
  • 如果找到匹配的 IP 地址,解析过程结束。
步骤 3:检查路由器缓存
  • 如果操作系统缓存中没有,请求会发送到本地路由器,路由器可能也缓存了 DNS 记录。
步骤 4:向本地 DNS 服务器发送请求
  • 如果以上缓存都没有,浏览器会向本地 DNS 服务器(通常由 ISP 提供)发送 DNS 查询请求。
  • 本地 DNS 服务器通常缓存了大量域名解析结果,如果找到匹配的 IP 地址,直接返回。
步骤 5:递归查询
  • 如果本地 DNS 服务器没有缓存,它会开始递归查询:

    1. 根域名服务器:本地 DNS 服务器首先向根域名服务器查询,根域名服务器返回顶级域名服务器(如 .com)的地址。
    2. 顶级域名服务器:本地 DNS 服务器向顶级域名服务器查询,顶级域名服务器返回权威域名服务器(如 example.com)的地址。
    3. 权威域名服务器:本地 DNS 服务器向权威域名服务器查询,权威域名服务器返回目标域名的 IP 地址。
步骤 6:返回结果
  • 本地 DNS 服务器将查询到的 IP 地址返回给浏览器,并缓存该结果以备后续使用。
步骤 7:浏览器获取 IP 地址
  • 浏览器收到 IP 地址后,缓存该结果,并使用该 IP 地址与服务器建立连接

2.建立连接

(1. TCP连接(三次握手)

TCP(传输控制协议)是一种面向连接的协议,确保数据可靠传输。建立TCP连接需要通过“三次握手”来确认双方的通信能力。

三次握手的过程:
  1. 第一次握手(SYN):

    • 客户端(浏览器)向服务器发送一个带有 SYN(同步)标志 的数据包,表示请求建立连接。
    • 客户端进入 SYN_SENT 状态。
  2. 第二次握手(SYN-ACK):

    • 服务器收到客户端的SYN请求后,如果同意建立连接,会发送一个带有 SYN-ACK(同步-确认)标志 的数据包作为响应。
    • 服务器进入 SYN_RECEIVED 状态。
  3. 第三次握手(ACK):

    • 客户端收到服务器的SYN-ACK响应后,会发送一个带有 ACK(确认)标志 的数据包,表示连接已建立。
    • 服务器收到ACK后,连接正式建立,双方进入 ESTABLISHED 状态。
三次握手的作用:
  • 确保客户端和服务器的发送和接收能力正常。
  • 协商初始序列号(ISN),用于后续数据传输的排序和确认。

(2. SSL/TLS握手(HTTPS)

如果URL使用的是HTTPS协议(基于SSL/TLS加密),在TCP连接建立后,还需要进行SSL/TLS握手,以确保通信的安全性。

SSL/TLS握手的过程:
  1. 客户端Hello:

    • 客户端向服务器发送一个 Client Hello 消息,包含以下信息:

      • 支持的TLS版本。
      • 客户端生成的随机数(用于后续密钥生成)。
      • 支持的加密算法(Cipher Suites)。
      • 支持的压缩方法(可选)。
  2. 服务器Hello:

    • 服务器向客户端发送一个 Server Hello 消息,包含以下信息:

      • 选择的TLS版本。
      • 服务器生成的随机数(用于后续密钥生成)。
      • 选择的加密算法。
      • 服务器的数字证书(包含公钥)。
  3. 服务器证书验证:

    • 客户端验证服务器的数字证书是否有效(是否由受信任的证书颁发机构签发,是否在有效期内,域名是否匹配等)。
    • 如果验证失败,客户端会终止连接。
  4. 密钥交换:

    • 客户端生成一个 预主密钥(Pre-Master Secret) ,并使用服务器的公钥加密后发送给服务器。
    • 服务器使用自己的私钥解密,获取预主密钥。
  5. 生成会话密钥:

    • 客户端和服务器使用客户端随机数、服务器随机数和预主密钥,通过相同的算法生成 会话密钥(Session Key)
    • 会话密钥用于后续通信的对称加密。
  6. 完成握手:

    • 客户端和服务器分别发送 Finished 消息,使用会话密钥加密,验证握手过程是否成功。
    • 如果验证通过,SSL/TLS握手完成,双方可以开始加密通信。

3.发送请求

(1. 构建HTTP请求

HTTP请求由三部分组成:请求行请求头 和 请求体。浏览器根据用户的操作和上下文信息构建这些部分。

1.1 请求行(Request Line)

请求行是HTTP请求的第一行,包含以下信息:

  • 请求方法:表示请求的类型,常见的有:

    • GET:请求资源(如HTML页面、图片等)。
    • POST:提交数据(如表单数据)。
    • PUT:更新资源。
    • DELETE:删除资源。
    • HEAD:请求资源的头部信息。
  • 请求路径:URL中域名之后的部分,例如 /index.html

  • HTTP版本:通常是 HTTP/1.1 或 HTTP/2

GET /index.html HTTP/1.1
1.2 请求头(Request Headers)

请求头包含一些附加信息,用于描述客户端的能力、请求的上下文等。常见的请求头包括:

  • Host:请求的目标域名(例如 www.example.com)。
  • User-Agent:客户端的信息(如浏览器类型、操作系统等)。
  • Accept:客户端能够接收的响应内容类型(如 text/html)。
  • Accept-Language:客户端优先接收的语言(如 en-US)。
  • Accept-Encoding:客户端支持的压缩算法(如 gzip)。
  • Cookie:客户端存储的Cookie信息。
  • Referer:当前请求的来源页面。
  • Authorization:身份验证信息(如Bearer Token)。
Host: www.example.com
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8
Accept-Language: en-US,en;q=0.9
Accept-Encoding: gzip, deflate, br
Cookie: sessionId=abc123
1.3 请求体(Request Body)

请求体通常用于 POSTPUT 等方法,包含客户端发送给服务器的数据。对于 GET 请求,请求体通常为空。请求体的格式可以是:

  • 表单数据(application/x-www-form-urlencoded)。
  • JSON数据(application/json)。
  • 文件数据(multipart/form-data)。
username=test&password=123456

(2. 发送HTTP请求

构建好HTTP请求后,浏览器会通过之前建立的TCP连接(或HTTP/2的多路复用连接)将请求发送到服务器。

2.1 发送请求行和请求头
  • 浏览器首先发送请求行和请求头。
  • 如果是HTTP/1.1,请求行和请求头会以纯文本形式发送。
  • 如果是HTTP/2,请求行和请求头会被二进制编码并分帧发送。
2.2 发送请求体
  • 如果请求包含请求体(如 POST 请求),浏览器会在请求头之后发送请求体。
  • 请求体的发送可能会分块进行,具体取决于请求的大小和服务器的支持。

(3. 请求的优化

为了提高性能和效率,浏览器和服务器可能会对请求进行一些优化:

3.1 持久连接(HTTP/1.1 Keep-Alive)
  • 在HTTP/1.1中,默认启用持久连接(Keep-Alive),即同一个TCP连接可以用于多个请求,避免重复建立连接的开销。
3.2 HTTP/2 多路复用
  • HTTP/2 支持多路复用,即多个请求可以同时通过同一个TCP连接发送,避免了HTTP/1.1中的队头阻塞问题。
3.3 压缩
  • 请求头可以通过HPACK算法(HTTP/2)或Gzip压缩,减少传输的数据量。
3.4 缓存
  • 如果请求的资源已经被缓存,浏览器可能会直接使用缓存,而不会发送请求。

4.服务器处理

(1. 服务器收到请求

  • 浏览器发送一个HTTP请求到服务器,比如请求一个网页或提交表单。
  • 服务器收到这个请求后,开始处理。

(2. 服务器解析请求

  • 服务器会拆解请求的内容,弄清楚:

    • 你要什么:比如是请求一个网页(GET)还是提交数据(POST)。
    • 你要的资源:比如 /index.html 或 /api/data
    • 附加信息:比如浏览器的类型、Cookie、语言偏好等。

(3. 服务器决定怎么处理

  • 根据请求的内容,服务器决定怎么处理:

    • 如果是静态文件(比如HTML、CSS、图片):服务器直接找到文件并返回。
    • 如果是动态内容(比如需要从数据库获取数据):服务器会运行一段程序(如PHP、Python代码)来生成内容。

(4. 服务器执行操作

  • 服务器可能会做一些事情来生成响应:

    • 查数据库:比如获取用户信息或产品列表。
    • 验证身份:比如检查用户是否登录。
    • 调用其他服务:比如调用支付接口。

(5. 服务器生成响应

  • 服务器把处理结果打包成一个HTTP响应,包括:

    • 状态码:比如 200 表示成功,404 表示找不到资源。
    • 响应头:比如告诉浏览器返回的内容是什么类型(HTML、JSON等)。
    • 响应体:比如实际的网页内容或数据。

(6. 服务器返回响应

  • 服务器把生成的响应发送回浏览器。
  • 浏览器收到后,开始渲染页面或处理数据。

举个简单的例子

  1. 你访问一个网页https://www.example.com/index.html
  2. 服务器收到请求:发现你要的是 index.html
  3. 服务器处理:找到这个文件。
  4. 服务器生成响应:返回 index.html 的内容。
  5. 你看到网页:浏览器收到文件后,显示网页内容。

5.浏览器渲染

(1. 解析HTML,构建DOM树

  • 输入:浏览器接收到服务器返回的HTML文件。

  • 过程

    • 浏览器逐行读取HTML代码,将其解析成一个个节点(Node)
    • 这些节点按照层级关系组成一棵DOM树(Document Object Model)
    • DOM树是页面的结构化表示,每个HTML标签(如 <div><p>)都对应一个节点。

(2. 解析CSS,构建CSSOM树

  • 输入:浏览器接收到CSS文件或内联样式。

  • 过程

    • 浏览器解析CSS规则,生成CSSOM树(CSS Object Model)
    • CSSOM树描述了每个节点的样式信息(如颜色、字体、布局等)。
    • CSSOM树和DOM树是独立的,但它们最终会结合起来。

(3. 合并DOM和CSSOM,生成渲染树(Render Tree)

  • 过程

    • 浏览器将DOM树和CSSOM树合并,生成渲染树
    • 渲染树只包含需要显示的节点(例如,display: none 的元素不会出现在渲染树中)。
    • 每个节点都包含其样式信息和布局信息。

(4. 布局(Layout)

  • 过程

    • 浏览器根据渲染树计算每个节点的几何信息(如位置、大小)。
    • 这个过程也叫 重排(Reflow)
    • 布局的结果是一个“盒子模型”,确定了每个元素在页面中的具体位置。

6.页面展示

  1. 合成图层:将多个图层合成为最终图像。
  2. 显示图像:将图像传递给操作系统并显示在屏幕上。
  3. 处理用户交互:捕获用户操作并更新页面。
  4. 重绘与重排:根据页面变化重新绘制或布局。
  5. 页面更新:动态更新页面内容并显示。