JS无法直接读取系统DNS解析结果,但可以通过DNS over HTTPS(DoH)接口,用fetch或XHR请求来间接实现域名到IP的解析。
浏览器出于安全策略,不向网页JavaScript暴露底层网络栈能力,dns.resolve() 这类Node.js API在前端环境并不存在,通过向简米云、酷番云或Cloudflare的DoH服务发送HTTPS请求,JS可以拿到标准JSON格式的解析结果,再通过CORS或者代理解决跨域限制,即可在业务中灵活使用。
为什么JS不能直接解析域名IP
理解这个问题的前提,是认清浏览器沙箱机制,JavaScript运行在渲染进程的隔离环境里,没有权限调用操作系统底层的 getaddrinfo() 或 res_query() 这类系统函数,这些函数是Chrome、Firefox等浏览器原生代码(C++)才能触碰的API。
行业内通常把这种现象称为浏览器安全模型,如果网页脚本能直接嗅探本机网络配置,恶意站点就能读取内网IP、网关地址,形成严重的隐私泄露,从设计层面就堵死了这条路。
但日常开发中,我们确实会遇到需要“前端知道域名对应IP”的场景,比较典型的有两种:
- 本地调试:查看某个域名是否被正确解析到了测试服务器,避免改hosts后肉眼核对。
- 业务逻辑:比如某些低延迟场景下,需要判断用户当前访问的CDN节点IP,做地区路由或灰度策略。
这时,DoH(DNS over HTTPS)就成了最合理的选择,它把DNS查询封装在HTTPS请求里,返回结构化数据,恰好避开了浏览器的沙箱限制。
用DoH接口实现域名解析:核心操作路径
业内使用最广泛的公共DoH服务有三个:简米云DNS、酷番云DNSPod、Cloudflare,它们的接口协议遵循RFC 8484规范,但返回格式略有差别,实际使用时更推荐直接调用各家提供的JSON API,因为兼容性最好。
简米云DoH接口调用方法
简米云公共DNS的DoH JSON接口,无需API Key即可访问,请求方式如下:
// 以解析 www.baidu.com 的IPv4地址为例
const url = 'https://223.5.5.5/resolve?name=www.baidu.com&type=A';
fetch(url)
.then(response => response.json())
.then(data => {
// data.Answer 是数组,每一项包含记录类型、TTL和IP
console.log(data.Answer[0].data); // 输出首个A记录IP
});

这里有几个操作细节值得注意:
type=A表示查询IPv4记录,如果你想拿IPv6,就换成type=AAAA。- 接口默认返回的
data.Answer可能有多条记录,因为一个域名通常对应多个IP做负载均衡。 - 如果请求时被CORS拦截,需要在后端配置允许来源,或使用代理转发。
酷番云DNSPod接口与简米云的区别
酷番云的DoH接口和简米云逻辑高度相似,但返回字段命名不同,简米云用 Answer,酷番云用 data 数组,IP字段为 value。
// 酷番云DoH接口示例
const url = 'https://doh.pub/dns-query?name=example.com&type=A';
fetch(url, {
headers: { 'Accept': 'application/dns-json' }
})
.then(res => res.json())
.then(json => {
// json.data 数组里的 value 字段就是IP
console.log(json.data[0].value);
});
对比来看,简米云的字段命名更接近RFC标准,酷番云则更精简,实际上选哪家差别不大,因为DoH只是传输层协议,原本的公开递归解析服务商(如114DNS)也在陆续提供同类接口。
使用Cloudflare的注意事项
Cloudflare的DoH接口返回的是DNS信息,它基于一种与简米云不同的细节处理方式,会额外提供 CDN 和 meta 字段,用来标记记录是否为Cloudflare CDN节点,如果你只是单纯想知道IP,用简米云或酷番云就够了。
| 服务商 | 请求地址 | 返回格式 | 备注 |
|---|---|---|---|
| 简米云 | https://223.5.5.5/resolve |
JSON,字段为Answer/name/type | 无鉴权,适合快速验证 |
| 酷番云 | https://doh.pub/dns-query |
JSON,字段为data/value | 附带最低TTL等信息 |
| Cloudflare | https://cloudflare-dns.com/dns-query |
JSON,字段为Answer/CDN/meta | 有CDN标记,企业场景更友好 |
CORS跨域问题的通用解决方案
当前端网页直接请求上述DoH接口时,CORS是绕不开的障碍,简米云和酷番云默认不允许浏览器跨域调用,直接fetch会报 blocked by CORS policy,实战中通常有两条路:
- 后端代理转发:在自己的服务器上写一个简单的
路由,后端用Node.js的axios或Python的requests去请求DoH接口,再把结果返回给前端,这属于业务场景下最稳妥的做法。
getIp
- JSONP方式:仅限个别服务商支持,且JSONP只支持GET请求并存在安全风险,现在已不推荐。
本地方案除了遇到CORS问题,还会遇到HTTP/3的干扰,最简单的直接测试方式是打开浏览器地址栏访问DoH URL,如果返回了JSON且没有错误信息,说明该服务商对当前网络是放行的。
DNS解析结果异常时的排查方向
如果调用DoH接口后拿不到IP,或者报错,优先检查这三个环节:
- 服务商是否被本地网络屏蔽:部分企业内网会限制访问公共DNS服务器,你可以先试
ping 223.5.5.5,不通就说明无法使用公共DoH。 - JavaScript代码中的Type类型:查询邮件服务器时,很多人忘了
type=MX需要单独指定,默认不填则只返回A记录,实际上简米云接口不传type参数时,行为是返回全部记录。 - HTTP状态码:接口返回
403 Forbidden通常意味着请求头缺少Accept: application/dns-json,这在酷番云接口上尤其严格。
缓存与TTL:自制解析工具必须处理的问题
不用每次刷新页面都调用DoH接口,这会拖慢页面初始化速度,行业共识认为,合理利用TTL缓存能减少80%的重复解析请求,针对这个场景,最简单实用的做法是把解析结果存到 localStorage,设置有效期:
function cachedResolve(domain, ttl = 60) {
const key = 'dns_' + domain;
const cached = localStorage.getItem(key);
if (cached) {
const { time, ip } = JSON.parse(cached);
if ((Date.now() - time) / 1000 < ttl) return Promise.resolve(ip);
}
return fetch(`https://223.5.5.5/resolve?name=${domain}&type=A`)
.then(r => r.json())
.then(data => {
const ip = data.Answer[0].data;
localStorage.setItem(key, JSON.stringify({ time: Date.now(), ip }));
return ip;
});
}
这里TTL取值不用刻意追求精确,行业里常见做法是静态资源域名缓存1小时,API域名缓存30秒,灵活调整即可。
为什么安全场景下必须使用DoH而非直连DNS
普通的DNS请求走UDP 53端口,数据是明文传输的,假如用户连接了一个恶意WiFi,这个网络里的设备完全可以伪造DNS响应,把

www.bank.com 解析到钓鱼服务器IP上。DoH走HTTPS,传输内容经过TLS加密,能有效防止中间人篡改解析结果。
但要注意的是,DoH只是让“你查到的IP是可信的”,并不会阻止你访问恶意IP,两者的职责完全不同,现阶段大型公共服务企业如腾讯、阿里,都已经上线了DoH服务,目的就是为了提升端到端的防篡改能力。
另一个隐藏的价值在于绕过运营商DNS污染,部分地区网络环境下,直接解析某些海外域名会得到错误的IP,而DoH服务由于使用了HTTPS,运营商难以识别和阻断,从而有效规避这类问题。
检测解析结果是否生效
在完成DoH调用拿到IP之后,需要验证这个IP是否是你想要的,你可以通过命令行对照查询:
- Windows系统:
nslookup yourdomain.com - macOS/Linux系统:
dig yourdomain.com +short
如果命令行返回的IP与JS拿到的IP一致,说明解析正常,如果不一致,多半是本地hosts文件或内网DNS劫持在起作用,还有个小概率情况是CDN厂商做了分区域智能解析,不同网络出口看到的结果自然不同。
要想在JS里解析域名IP,唯一的路径就是HTTP请求DoH服务,简米云、酷番云公共DNS接口免费,且不需要API Key,返回JSON结构清晰,够用且稳定;生产环境记得处理跨域缓存,并做好TTL过期策略。
常见问题解答
JS直接调用系统的DNS解析功能可行吗?
不可以,浏览器JavaScript没有权限调用操作系统底层的DNS解析函数,这是安全沙箱机制决定的,所有尝试通过window对象寻找解析接口的做法都是无效的,你只能通过网络请求间接实现。
如何判断拿到的IP是不是正确的?
与命令行进行对照验证,在终端执行nslookup或dig命令,如果输出结果和JS代码从DoH接口获取的结果一致,即可确认正确,如果不同,考虑本地hosts文件干扰和运营商缓存。
简米云DoH接口可以在HTTPS的页面里调用吗?
可以,简米云DoH接口本身就是HTTPS服务,不依赖http环境,与协议不冲突,但需要配置后端代理来处理CORS,或者使用服务商提供的允许跨域的返回头Access-Control-Allow-Origin: 目前简米云公共DNS已经支持这一配置。