公众号:小博的前端笔记
一:URL 输入全过程详解
整个过程分为 6 个核心阶段,每个阶段的关键步骤和技术细节如下:
阶段 1:URL 解析与预处理
-
输入处理
- 用户输入
example.com
或完整 URL(如https://www.example.com/path?key=value#section
)。 - 浏览器自动补全协议(HTTP/HTTPS)和路径(
/
)。 - 检查 HSTS 列表(强制 HTTPS),若域名在列表中,直接使用 HTTPS。
- 用户输入
-
URL 结构解析
协议: https 主机名: www.example.com 端口: 443(HTTPS 默认) 路径: /path 查询: ?key=value 哈希: #section(不发送到服务器)
阶段 2:DNS 域名解析
-
缓存查询(由近到远)
- 浏览器缓存 → 操作系统缓存(
hosts
文件) → 路由器缓存 → ISP DNS 缓存。 - 若命中缓存,直接返回 IP 地址。
- 浏览器缓存 → 操作系统缓存(
-
递归查询(未命中缓存时)
-
浏览器向 本地 DNS 服务器(如
8.8.8.8
)发起请求。 -
本地 DNS 服务器依次查询:
- 根域名服务器(
.
) → 返回.com
顶级域名服务器地址 - 顶级域名服务器(
.com
) → 返回example.com
权威域名服务器地址 - 权威域名服务器 → 返回
www.example.com
的 IP 地址(如93.184.216.34
)。
- 根域名服务器(
-
-
DNS 优化
- DNS 预解析:
<link rel="dns-prefetch" href="//example.com">
- CDN 调度:权威 DNS 可能根据用户位置返回最近的 CDN 节点 IP。
- DNS 预解析:
阶段 3:建立网络连接
-
TCP 三次握手
- 客户端 → 服务器:
SYN
(序列号 =x
) - 服务器 → 客户端:
SYN-ACK
(序列号 =y
, 确认号 =x+1
) - 客户端 → 服务器:
ACK
(确认号 =y+1
) - 连接建立后进入 全双工通信状态。
- 客户端 → 服务器:
-
TLS 握手(HTTPS 场景)
- Client Hello:客户端发送支持的 TLS 版本、加密套件、随机数。
- Server Hello:服务器选定加密套件,发送证书和随机数。
- 验证证书:浏览器检查证书有效性(颁发机构、过期时间、域名匹配)。
- 密钥交换:客户端用证书公钥加密预主密钥发送给服务器。
- 生成会话密钥:双方用随机数 + 预主密钥生成对称加密密钥(如 AES)。
- 加密通信:后续数据通过对称加密传输(性能更高)。
阶段 4:发送 HTTP 请求与服务器处理
-
构建 HTTP 请求
GET /path?key=value HTTP/1.1 Host: www.example.com Connection: keep-alive User-Agent: Mozilla/5.0 Accept: text/html Cookie: name=value
- 若为 POST 请求,包含请求体(如
FormData
或 JSON)。
- 若为 POST 请求,包含请求体(如
-
服务器处理流程
- 反向代理(如 Nginx)接收请求,转发到应用服务器(如 Node.js、Tomcat)。
- 应用服务器执行业务逻辑(数据库查询、API 调用等)。
- 生成响应:状态码(200)、响应头(
Content-Type
、Cache-Control
)、响应体(HTML)。
阶段 5:浏览器接收响应与渲染
-
处理响应
-
检查状态码:
301/302
:根据Location
重定向(重新开始全过程)。200
:解析响应体(若Content-Encoding: gzip
则解压)。
-
-
渲染流水线(关键步骤)
- 构建 DOM 树:将 HTML 解析为树状结构,遇到
<script>
暂停解析(除非async/defer
)。 - 构建 CSSOM:解析 CSS 样式,生成样式规则树。
- 合并 Render 树:结合 DOM + CSSOM,排除不可见元素(如
display: none
)。 - 布局(Layout) :计算每个节点的位置和尺寸(重排 Reflow)。
- 绘制(Paint) :将布局转换为像素(分层绘制 → 合成)。
- 合成(Composite) :将各图层合并为最终页面(GPU 加速)。
- 构建 DOM 树:将 HTML 解析为树状结构,遇到
-
加载子资源
- 解析到
<img>
,<script>
,<link>
时,发起异步请求。 - 受限于同域名 TCP 连接数(HTTP/1.1 默认 6 个,HTTP/2 多路复用无限制)。
- 解析到
阶段 6:连接终止与后续行为
-
TCP 四次挥手
- 客户端 → 服务器:
FIN
(请求关闭) - 服务器 → 客户端:
ACK
(确认) - 服务器 → 客户端:
FIN
(服务器关闭) - 客户端 → 服务器:
ACK
(最终确认)
- 客户端 → 服务器:
-
后续行为
- 事件触发:执行
DOMContentLoaded
(DOM 解析完成)和load
(所有资源加载完成)。 - 保持连接:若响应头含
Connection: keep-alive
,TCP 连接复用(避免重复握手)。
- 事件触发:执行
知识普及:递归查询(Recursive Query) 和 缓存查询(由近到远)的区别
核心结论
-
缓存查询(由近到远) 是递归查询的 性能优化手段
-
递归查询 是 DNS 解析的 完整流程(包含缓存查询 + 外部查询)
-
二者关系可概括为:
“递归查询 = 缓存检查(由近到远) + 未命中时的外部层级查询”
一、缓存查询(由近到远)的本质
-
是什么? 在发起递归查询之前或过程中,按顺序检查多级缓存(类似“就近问路”):
-
目的:避免重复外部查询,加速解析(缓存命中则直接返回 IP)
-
特点:
- 纯本地行为(不涉及外部 DNS 服务器)
- 严格遵循 层级顺序(由近到远)
二、递归查询(Recursive Query)的本质
- 是什么? DNS 客户端(如 ISP 的服务器)代理用户完成全链条查询的行为:
-
触发条件:所有缓存均未命中(缓存查询失败)
-
责任方:由 递归 DNS 服务器(如
8.8.8.8
)执行 -
特点:
- 客户端只需发一次请求 → 递归 DNS 负责层层追问直到拿到最终 IP
- 递归 DNS 会缓存结果供后续使用
✅ 关键解读:
- 缓存查询(由近到远)是递归查询触发前的本地行为
- 递归 DNS 服务器自身也有缓存(二次缓存检查)
- 所有缓存未命中 → 执行真正的递归查询(根→顶级→权威)
二:加分点
-
性能优化关联
- DNS 预解析、HTTP/2 多路复用、CDN、资源压缩(Brotli)、缓存策略(
Cache-Control
)。
- DNS 预解析、HTTP/2 多路复用、CDN、资源压缩(Brotli)、缓存策略(
-
安全相关问题
- HTTPS 防止中间人攻击、HSTS 防劫持、证书透明度(CT)。
-
关键渲染路径优化
- CSS 放在头部(避免阻塞渲染)、JS 异步加载、减少重排/重绘。
-
HTTP 协议演进
- HTTP/1.1 队头阻塞 vs HTTP/2 帧复用 vs HTTP/3 QUIC(基于 UDP)。
三:简洁版
“当输入 URL 后:
- 浏览器解析 URL 并检查缓存(强制/协商缓存)/HSTS(强制浏览器只通过 HTTPS 访问网站,彻底阻止 HTTP 明文传输。);
- DNS 解析获取 IP;
- TCP 三次握手建立连接,若是 HTTPS 则进行 TLS 握手;
- 发送 HTTP 请求,服务器处理并返回响应;
- 浏览器解析 HTML/CSS 构建 DOM/CSSOM,合并渲染树后布局绘制;
- 加载子资源并执行 JS,触发 DOMContentLoaded 和 load 事件;
- 最后 TCP 四次挥手断开连接(或复用连接)。”
知识普及:HSTS 是什么?为什么需要它?
✅ HSTS(HTTP Strict Transport Security)
-
核心作用: 强制浏览器只通过 HTTPS 访问网站,彻底阻止 HTTP 明文传输。
-
诞生背景:
- 用户手动输入
http://example.com
或点击 HTTP 链接时 - 中间人攻击(如公共 WiFi)可劫持 HTTP 请求 → 实施钓鱼或篡改
- HSTS 解决:首次访问后,浏览器自动将所有 HTTP 转为 HTTPS
- 用户手动输入
四:路由器缓存 、 ISP DNS 缓存分别是什么
1. 路由器缓存(Router Cache)是什么
- 路由器在本地网络(如家庭或办公室)中维护的一个小型 DNS 缓存。
- 当设备(电脑、手机等)通过路由器访问网络时,路由器会临时存储已解析的域名和 IP 地址的映射关系。
工作流程:
-
设备(如电脑)向路由器发起 DNS 查询(例如
www.example.com
)。 -
路由器检查自身缓存:
- 若缓存中有该域名记录(且未过期),直接返回 IP 地址(无需向外查询)。
- 若缓存中无记录,路由器作为代理,向上一级(通常是 ISP DNS 服务器)发起查询。
-
路由器将查询结果缓存一段时间(根据 DNS 记录的 TTL 值,通常几分钟到几小时)。
特点:
- 作用范围:仅限当前局域网内的所有设备(共享缓存)。
- 优势:减少局域网内重复查询的延迟(例如同一 WiFi 下多台设备访问同一网站)。
- 劣势:缓存容量小,过期策略依赖 TTL。
2. ISP DNS 缓存(Internet Service Provider DNS Cache)
是什么?
- 由用户的互联网服务提供商(如电信、联通、Comcast 等)维护的大型公共 DNS 缓存服务器。
- ISP 为所有接入该网络的用户提供 DNS 解析服务,并缓存热门域名的解析结果。
工作流程:
-
若路由器缓存未命中,查询会转发到 ISP 的 DNS 服务器(如
8.8.8.8
是 Google 的公共 DNS,非 ISP)。 -
ISP DNS 服务器检查自身缓存:
- 若有记录且未过期,直接返回 IP 地址。
- 若无记录,则向根域名服务器发起递归查询(完整 DNS 解析流程)。
-
ISP 将最终结果缓存,并返回给用户的路由器。
特点:
-
作用范围:该 ISP 网络下的所有用户(千万级设备共享)。
-
优势:
- 大幅减少全球 DNS 查询压力(尤其是热门网站)。
- 通过 CDN 调度返回离用户最近的 IP(提升访问速度)。
-
劣势:
- 可能因缓存过期导致延迟更新(依赖 TTL)。
- 存在隐私风险(ISP 可记录用户的访问历史)。
缓存层级对比表
特性 | 路由器缓存 | ISP DNS 缓存 |
---|---|---|
控制方 | 本地路由器 | 互联网服务提供商(ISP) |
作用范围 | 单个局域网(如家庭/办公室) | ISP 所有用户(如全省用户) |
缓存时效 | 较短(通常几小时) | 较长(遵循 DNS 记录的 TTL) |
查询速度 | 极快(局域网内纳秒级响应) | 较快(跨网络毫秒级响应) |
隐私性 | 较高(数据仅在本地) | 较低(ISP 可能记录查询日志) |
典型应用场景 | 多设备访问同一网站(如家庭 WiFi) | 全网用户访问热门站点(如 Google) |
DNS 缓存全链条(由近到远)
当浏览器发起 DNS 查询时,按顺序检查以下缓存:
- 浏览器缓存:浏览器自身的 DNS 记录(如 Chrome 的
net-internals
)。 - 操作系统缓存:系统的 Hosts 文件(
/etc/hosts
)和 DNS 缓存(Windows 的ipconfig/displaydns
)。 - 路由器缓存:局域网网关的临时存储。
- ISP DNS 缓存:互联网提供商的共享缓存。
- 外部 DNS 递归查询:若以上均未命中,触发完整 DNS 解析流程。
提问总结
问题:”DNS 解析过程中,路由器缓存和 ISP 缓存的作用是什么?“ 回答: “DNS 解析是一个多级缓存加速的过程。
- 路由器缓存是局域网内的共享缓存,当同一网络下的设备重复访问同一域名时,路由器可直接返回 IP 地址,减少对外查询。
- ISP DNS 缓存由宽带运营商维护,服务于所有接入用户。它通过缓存热门域名的解析结果,降低全球 DNS 服务器的压力,同时结合 CDN 返回最优 IP 提升访问速度。 这两级缓存共同减少了 DNS 解析延迟,是优化网页加载的重要环节。”
五:什么是 TTL
TTL(Time To Live,生存时间) 是计算机网络中一个关键的时间控制参数,用于指定数据(如 DNS 记录、IP 数据包)的有效存活时长。在 DNS 场景中,TTL 直接决定了缓存服务器(如路由器、ISP DNS)保存域名解析结果的时长。
1、DNS TTL 的核心作用
-
控制缓存时效:当 DNS 记录被缓存后,TTL 值(单位为秒)开始倒计时。
-
过期失效:一旦 TTL 归零,缓存服务器会丢弃该记录,强制重新查询权威 DNS 获取最新结果。
-
平衡性能与一致性:
- 高 TTL(如 86400 秒=1 天)→ 缓存时间长 → 减少查询次数(性能好),但更新延迟高。
- 低 TTL(如 300 秒=5 分钟)→ 缓存时间短 → 记录更新及时,但查询压力大(性能差)。
2、DNS TTL 的工作流程
示例:
- 权威 DNS 返回记录
www.example.com A 93.184.216.34
,并设置TTL=3600
(1 小时)。 - 本地 DNS 服务器缓存该记录,并在接下来 1 小时内直接响应相同查询。
- 1 小时后(TTL 归零),下一个查询触发重新解析。
3、正确查看 DNS TTL 的 3 种方法
✅ 方法 1:命令行工具(推荐)
# Linux/macOS (dig)
dig example.com +noall +answer
# Windows (nslookup)
nslookup -debug example.com
输出示例:
example.com. 300 IN A 93.184.216.34
# ↑ TTL=300 秒 (5 分钟)
✅ 方法 2:浏览器内部查看(仅限调试)
- Chrome 地址栏输入:
chrome://net-internals/#dns
- 查看 "Host resolver cache" 列表
- 找到目标域名, "expiration" 字段即 TTL 过期时间
✅ 方法 3:在线 DNS 查询工具
4、TTL 导致延迟更新的场景
假设某网站需要迁移服务器(IP 变更):
-
管理员操作:
- 在权威 DNS 将
www.example.com
的 A 记录从旧 IP1.1.1.1
改为新 IP2.2.2.2
。 - 但 TTL 仍为 24 小时(86400 秒) 。
- 在权威 DNS 将
-
用户访问问题:
- 在 TTL 过期前,所有缓存服务器(如 ISP DNS)仍返回旧 IP
1.1.1.1
。 - 用户可能最长需要 24 小时才能访问到新 IP(实际因缓存层级差异,时间可能更短)。
- 在 TTL 过期前,所有缓存服务器(如 ISP DNS)仍返回旧 IP
💡 最佳实践: 迁移前提前降低 TTL(如改为 300 秒),确保缓存快速过期。迁移完成后再恢复高 TTL。
5、TTL 在不同协议中的应用
协议/场景 | TTL 作用 |
---|---|
DNS | 控制域名解析结果的缓存时间(如 dig example.com 返回的 ANSWER SECTION 中的数值)。 |
HTTP | 响应头 Cache-Control: max-age=60 控制资源缓存时间(类似逻辑)。 |
IP 协议 | 数据包每经过一个路由器 TTL 减 1,归零则丢弃(防环路)。 |
CDN | 边缘节点缓存资源的时长(通常继承 HTTP max-age 或自定义)。 |
6、如何手动设置 TTL?
通用操作流程(以主流服务商为例):
-
登录 DNS 托管平台 Cloudflare / AWS Route 53 / 阿里云 DNS / DNSPod(腾讯云)等控制台。
-
选择目标域名
-
编辑 DNS 记录
- 找到需要修改的记录类型(A、CNAME、MX 等)
- 点击编辑按钮(通常为铅笔图标)
-
修改 TTL 值
- 在
TTL
字段输入新值(单位:秒) - 保存更改
- 在
不同服务商操作界面示例:
服务商 | 操作路径 |
---|---|
Cloudflare | DNS → 记录 → 编辑 → TTL(支持自动/手动) |
AWS Route 53 | Hosted Zones → 域名 → 编辑记录 → TTL |
阿里云 | 域名解析 → 解析设置 → 修改记录 → TTL |
聚名网 | 本菜鸡没找到! |
提问
问题:“DNS 中的 TTL 是什么?为什么它会导致缓存更新延迟?” 回答: “TTL(Time To Live)是 DNS 记录的生存时间值(单位:秒),由权威 DNS 服务器设置。
- 它告知递归 DNS(如 ISP 的服务器)该记录允许被缓存多久。
- 若 TTL 未过期,缓存服务器直接返回结果,不再查询权威 DNS;
- 若 TTL 过期(归零),则强制重新解析。
延迟更新问题: 当管理员修改 DNS 记录(如切换服务器 IP)时,若旧记录的 TTL 较长(例如 24 小时),全球缓存服务器在 TTL 过期前仍返回旧结果,导致用户最长需等待 TTL 时长才能获取新记录。”