跳到主要内容

DNS 域名解析

问题

DNS 是什么?域名解析的完整过程是怎样的?前端如何优化 DNS?

面试速答版

DNS 是什么?为什么重要? DNS 是互联网的「电话簿」,把 www.example.com 翻译成 93.184.216.34

  • 浏览器只会拿域名向 DNS 系统查 IP,拿到 IP 才能发起 TCP 连接。
  • DNS 解析是页面加载第一步,多 100ms 就是首屏多 100ms,所以前端要关心。
  • 默认走 UDP 53 端口(包小、快),结果太大或区域传送时降级 TCP。

DNS 解析的完整过程? 按缓存层级一层层往外查,命中就返回:

  • 浏览器缓存操作系统缓存(含 hosts 文件)本地 DNS(运营商/8.8.8.8
  • 本地 DNS 没命中就发起递归查询:先问根服务器.com 顶级地址 → 问顶级域服务器example.com 权威地址 → 问权威服务器拿最终 IP。
  • 沿途每一级都会按 TTL 缓存结果。改了 DNS 解析为什么短期不生效?就是 TTL 没过期。

前端能做哪些 DNS 优化? 核心是预解析减少域名数

  • <link rel="dns-prefetch" href="//cdn.example.com">:提前解析跨域资源域名,节省一次 RTT。
  • <link rel="preconnect"> 更激进,连 TCP+TLS 都提前建好。
  • 合理控制使用的域名数:太少会受 HTTP/1.1 的 6 个并发限制(HTTP/2 后已不重要);太多会让 DNS 解析次数暴涨。
  • 选靠谱 DNS 服务(HTTPDNS)能避免运营商劫持、就近解析。

答案

DNS(Domain Name System,域名系统)是互联网的"电话簿",负责将人类可读的域名转换为机器可识别的 IP 地址。

DNS 作用


DNS 解析过程

完整流程

详细步骤

步骤说明
1. 浏览器缓存检查浏览器 DNS 缓存
2. 系统缓存检查操作系统 DNS 缓存
3. hosts 文件检查本地 hosts 文件
4. 本地 DNS查询 ISP 的 DNS 服务器
5. 根 DNS查询根域名服务器(.)
6. 顶级 DNS查询顶级域名服务器(.com)
7. 权威 DNS查询域名的权威服务器
8. 返回结果逐级返回并缓存

DNS 缓存层级

各级缓存

层级TTL查看方式
浏览器缓存1分钟左右chrome://net-internals/#dns
系统缓存取决于 TTLWindows: ipconfig /displaydns
本地 DNS取决于 TTL由 ISP 管理
# 清除系统 DNS 缓存
# Windows
ipconfig /flushdns

# macOS
sudo dscacheutil -flushcache

# Linux
sudo systemd-resolve --flush-caches

DNS 记录类型

类型说明示例
AIPv4 地址example.com → 93.184.216.34
AAAAIPv6 地址example.com → 2606:2800:220:1:...
CNAME别名记录www.example.com → example.com
MX邮件服务器example.com → mail.example.com
TXT文本记录域名验证、SPF
NS域名服务器example.com → ns1.example.com
# 查询 DNS 记录
# A 记录
nslookup example.com
dig example.com A

# CNAME 记录
dig www.example.com CNAME

# 所有记录
dig example.com ANY

前端 DNS 优化

1. DNS 预解析

<!-- 预解析第三方域名 -->
<link rel="dns-prefetch" href="//cdn.example.com">
<link rel="dns-prefetch" href="//api.example.com">
<link rel="dns-prefetch" href="//fonts.googleapis.com">

<!-- 强制开启 DNS 预解析(HTTPS 页面默认关闭) -->
<meta http-equiv="x-dns-prefetch-control" content="on">
使用场景
  • 第三方资源(CDN、统计、字体)
  • 页面跳转前预解析目标域名
  • 不要预解析当前域名(已经解析过了)

2. 预连接

<!-- 预连接:DNS + TCP + TLS -->
<link rel="preconnect" href="https://cdn.example.com">

<!-- 关键资源预连接 -->
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>

3. 减少 DNS 查询

// ❌ 多个域名
// cdn1.example.com
// cdn2.example.com
// cdn3.example.com
// api.example.com
// static.example.com

// ✅ 合理的域名数量
// cdn.example.com (静态资源)
// api.example.com (API 请求)
// 控制在 2-4 个域名

4. 使用快速 DNS

// 公共 DNS 服务器
const publicDNS = {
google: ['8.8.8.8', '8.8.4.4'],
cloudflare: ['1.1.1.1', '1.0.0.1'],
alibaba: ['223.5.5.5', '223.6.6.6'],
tencent: ['119.29.29.29']
};

DNS 劫持与防护

DNS 劫持类型

类型说明危害
本地劫持hosts 文件被修改跳转到恶意网站
路由器劫持路由器 DNS 被篡改全家设备受影响
ISP 劫持运营商插入广告页面被注入内容
DNS 服务器劫持DNS 服务器被攻击大范围影响

防护措施

// 1. 使用 HTTPS
// 即使 DNS 被劫持,证书验证会失败

// 2. 使用 DoH (DNS over HTTPS)
// 浏览器设置中开启

// 3. 验证页面完整性
// 使用 SRI (Subresource Integrity)
<script
src="https://cdn.example.com/app.js"
integrity="sha384-..."
crossorigin="anonymous"
></script>

// 4. 前端检测
function checkDNSHijack() {
// 检查关键 API 是否可访问
fetch('https://api.example.com/health')
.catch(() => {
// 可能被劫持,上报或降级
reportError('DNS_HIJACK_SUSPECTED');
});
}

DNS 与 CDN

# 查看 CDN 解析过程
dig www.taobao.com

# 可能看到多级 CNAME
# www.taobao.com → www.taobao.com.danuoyi.tbcache.com
# → ... → 最终 IP

常见面试问题

Q1: DNS 解析过程?

答案

  1. 浏览器缓存:检查浏览器 DNS 缓存
  2. 系统缓存:检查操作系统缓存
  3. hosts 文件:检查本地 hosts
  4. 本地 DNS:查询 ISP DNS 服务器
  5. 递归查询
    • 根 DNS(.)→ 返回顶级 DNS 地址
    • 顶级 DNS(.com)→ 返回权威 DNS 地址
    • 权威 DNS → 返回目标 IP
  6. 缓存结果:各级缓存,下次直接返回

Q2: 如何优化 DNS 解析?

答案

<!-- 1. DNS 预解析 -->
<link rel="dns-prefetch" href="//cdn.example.com">

<!-- 2. 预连接(DNS + TCP + TLS) -->
<link rel="preconnect" href="https://api.example.com">

<!-- 3. 减少域名数量 -->
<!-- 控制在 2-4 个域名 -->

<!-- 4. 使用快速 DNS -->
<!-- 如 Cloudflare 1.1.1.1 -->

Q3: DNS 和 CDN 的关系?

答案

CDN 通过 DNS 实现智能调度:

  1. CNAME 跳转:域名 CNAME 到 CDN 域名
  2. 智能解析:CDN DNS 根据用户位置、负载返回最优节点
  3. 就近访问:用户访问最近的边缘节点
# 示例
www.example.com
→ CNAME: example.cdn.com
→ CDN DNS 智能解析
→ 返回最近节点 IP

Q4: 什么是 DNS 劫持?如何防护?

答案

DNS 劫持:攻击者篡改 DNS 解析结果,将用户引导到恶意网站。

防护措施

措施说明
HTTPS证书验证防止内容篡改
DoH/DoT加密 DNS 查询
SRI验证资源完整性
DNSSECDNS 签名验证

Q5: dns-prefetch、preconnect、prefetch 的区别?

答案

指令作用场景
dns-prefetch仅 DNS 解析第三方域名
preconnectDNS + TCP + TLS关键第三方资源
prefetch预加载资源下一页可能需要的资源
preload预加载当前页资源当前页关键资源
<!-- DNS 预解析 -->
<link rel="dns-prefetch" href="//example.com">

<!-- 预连接 -->
<link rel="preconnect" href="https://example.com">

<!-- 预获取资源 -->
<link rel="prefetch" href="/next-page.js">

<!-- 预加载当前页资源 -->
<link rel="preload" href="/critical.css" as="style">

相关链接