输入URL到页面渲染的完整流程解析

79 阅读4分钟

1、URL解析与预处理,主要是生成合法的URL

1.1 协议补全,端口

如果未指定协议(如http://), 浏览器默认补全为https://。 自动补全www前缀或后缀.com

1.2 字符串编码处理

地址中包含中文,转换为URL编码。

2、DNS域名解析:域名到IP地址的转换

2.1 缓存检查机制

  • 多级缓存策略:浏览器缓存---> 系统缓存(/etc/hosts)--->路由器缓存
  • 递归查询过程:本地DNS服务器-->根域名服务器-->顶级域名服务器-->权威域名服务器
    • 第一次请求,首先会在本地域名服务器中查找匹配的Ip地址。若没找到,本地域名服务器会向根域名服务器发送请求,进行IP匹配。若根域名服务器也不存在该域名,本地域名会向com顶级域名服务器发送请求,以此类推,直到找到所匹配的地址。

3、浏览器向服务器发出建立TCP连接申请,完成三次握手

3.1 第一次握手

客户端发送SYN包到服务器,进入SYN_SEND状态,等待服务器确认。

3.2 第二次握手

服务器收到SYN包,必须确认客户的SYN(ack=x+1),同时自己也发送一个SYN包(Seq=y),即SYN+ACK包,此时服务器进入SYN_RECV状态

3.3 第三次握手

客户端收到服务器的SYN+ACK包,向服务器发送确认包ACK(ack=y+1),此包发送完毕,客户端和服务器进入ESTABLISHED状态,完成三次握手

为啥需要三次握手?

三次握手”的目的是为了防止已失效的连接请求报文段突然又传送到了服务端,因而产生错误。

4、浏览器发送HTTP请求,get请求

4.1 请求报文结构

GET /index.html HTTP/1.1
Host: example.com
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.9,en;q=0.8
Accept-Encoding: gzip, deflate, br
Connection: keep-alive
Upgrade-Insecure-Requests: 1
Cache-Control: max-age=0
Cookie: sessionId=abc123; theme=dark

4.2关键请求头详解

4.2.1 Cookie处理

// Cookie的SameSite策略影响跨站请求
// Strict: 完全禁止跨站发送
// Lax: 导航请求可以发送(默认值)
// None: 允许跨站发送(需要Secure)
document.cookie = "sessionId=abc123; SameSite=Lax; Secure";

4.2.2 缓存控制

# 客户端缓存策略
Cache-Control: max-age=3600, must-revalidate
If-None-Match: "etag-value"
If-Modified-Since: Wed, 21 Oct 2023 07:28:00 GMT

4.2.3 内容协商

# 告知服务器支持的压缩格式
Accept-Encoding: gzip, deflate, br
# 告知服务器支持的内容类型
Accept: application/json, text/html

5、服务器处理请求并返回HTTP报文

5.1 响应报文分析

HTTP/1.1 200 OK
Date: Wed, 21 Oct 2023 07:28:00 GMT
Server: nginx/1.18.0
Content-Type: text/html; charset=utf-8
Content-Length: 12345
Content-Encoding: gzip
Cache-Control: public, max-age=3600
ETag: "abc123def456"
Last-Modified: Wed, 21 Oct 2023 06:00:00 GMT
Set-Cookie: sessionId=xyz789; Path=/; Secure; HttpOnly; SameSite=Lax
Strict-Transport-Security: max-age=31536000; includeSubDomains
X-Content-Type-Options: nosniff
X-Frame-Options: DENY
X-XSS-Protection: 1; mode=block

<!DOCTYPE html>
<html>
...

5.2 状态码

重定向类(3xx)

  • 301 Moved Permanently:永久重定向,搜索引擎会更新索引
  • 302 Found:临时重定向,搜索引擎保持原URL
  • 304 Not Modified:资源未修改,使用缓存

客户端错误(4xx)

  • 400 Bad Request:请求语法错误
  • 401 Unauthorized:需要身份验证
  • 403 Forbidden:服务器拒绝请求
  • 404 Not Found:资源不存在

服务器错误(5xx)

  • 500 Internal Server Error:服务器内部错误
  • 502 Bad Gateway:网关错误
  • 503 Service Unavailable:服务不可用

6、浏览器解析与渲染

步骤1:构建DOM树

    1. 创建Document对象
    1. 逐个解析HTML标签,创建对应的DOM节点
    1. 构建父子关系,形成DOM树

步骤2:构建CSSOM树

    1. 解析CSS规则
    1. 计算样式优先级
    1. 构建CSSOM(CSS Object Model)

步骤3:合并生成渲染树

步骤4:布局(Layout/Reflow)

步骤5:绘制(Paint)

步骤6: 合成(Composite)

7、根据情况判断是否断开连接:四次挥手

第一次挥手

客户端发送一个FIN,用来关闭客户端到服务端的数据传送,客户端进入FIN_WAIT_1(终止等待1)状态。

第二次挥手

服务端收到FIN包后,发送一个ACK给客户端,确认序号为收到序号+1(与SYN相同,一个FIN占用一个序号),服务端进入CLOSE-WAIT状态。客户端就进入FIN-WAIT-2(终止等待2)状态,等待服务器发送连接释放报文。

第三次挥手

服务端发送一个FIN,用来关闭服务端到客户端的数据传送,服务端就进入了LAST_ACK(最后确认)状态,等待客户端的确认。

第四次挥手

客户端收到FIN后,客户端进入TIME_WAIT状态,接着发送一个ACK给服务器,确认序号为收到序号+1,服务端进入CLOSED状态,完成四次挥手。