DNS 域名解析
问题
DNS 是什么?域名解析的完整过程是怎样的?前端如何优化 DNS?
答案
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 |
| 系统缓存 | 取决于 TTL | Windows: ipconfig /displaydns |
| 本地 DNS | 取决于 TTL | 由 ISP 管理 |
# 清除系统 DNS 缓存
# Windows
ipconfig /flushdns
# macOS
sudo dscacheutil -flushcache
# Linux
sudo systemd-resolve --flush-caches
DNS 记录类型
| 类型 | 说明 | 示例 |
|---|---|---|
| A | IPv4 地址 | example.com → 93.184.216.34 |
| AAAA | IPv6 地址 | 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 解析过程?
答案:
- 浏览器缓存:检查浏览器 DNS 缓存
- 系统缓存:检查操作系统缓存
- hosts 文件:检查本地 hosts
- 本地 DNS:查询 ISP DNS 服务器
- 递归查询:
- 根 DNS(.)→ 返回顶级 DNS 地址
- 顶级 DNS(.com)→ 返回权威 DNS 地址
- 权威 DNS → 返回目标 IP
- 缓存结果:各级缓存,下次直接返回
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 实现智能调度:
- CNAME 跳转:域名 CNAME 到 CDN 域名
- 智能解析:CDN DNS 根据用户位置、负载返回最优节点
- 就近访问:用户访问最近的边缘节点
# 示例
www.example.com
→ CNAME: example.cdn.com
→ CDN DNS 智能解析
→ 返回最近节点 IP
Q4: 什么是 DNS 劫持?如何防护?
答案:
DNS 劫持:攻击者篡改 DNS 解析结果,将用户引导到恶意网站。
防护措施:
| 措施 | 说明 |
|---|---|
| HTTPS | 证书验证防止内容篡改 |
| DoH/DoT | 加密 DNS 查询 |
| SRI | 验证资源完整性 |
| DNSSEC | DNS 签名验证 |
Q5: dns-prefetch、preconnect、prefetch 的区别?
答案:
| 指令 | 作用 | 场景 |
|---|---|---|
| dns-prefetch | 仅 DNS 解析 | 第三方域名 |
| preconnect | DNS + 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">