首发于个人博客:www.ahonn.me/post/57javascript
做为 Node.js 的内置模块之一,dns 模块平常的使用率并不高。但在某些状况下 dns 模块倒是很是有用的,例如在须要经过 Node.js 来判断本地网络是否畅通;或者在某些高并发的状况下,能够手动经过 dns 模块进行查询并缓存以后,再进行请求发送。html
因此 dns 模块仍是有必要好好了解了解的,毕竟说不定何时就用上了呢?java
做为一个合格的 dns 模块,必然是须要具有 DNS 解析的功能了。在 dns 模块中,用于解析的函数分为两种,一种是经过使用底层操做系统工具进行本地域名解析,且无需进行网络通讯。而另外一个则是经过链接 DNS 服务器进行域名解析。node
本地解析顾名思义就是不进行网络请求来进行解析,通常用来查看本地请求某个域名时,对应的 IP 地址是什么。dns 模块中经过 dns.lookup()
方法来进行本地域名解析,解析的过程相似于 ping
。缓存
const dns = require('dns');
dns.lookup('ahonn.me', (err, address, family) => {
if (err) {
throw err;
}
console.log('address: %s, family: IPv%s', address, family);
});
// address: 151.101.100.133, family: IPv4
复制代码
能够经过函数的第二个参数 options 来进行解析的设置,例如可以传入 { all: true }
,来获取全部的解析结果(包括 IPv4 与 IPv6)。服务器
除了 dns.lookup()
以外,dns 模块中的其余函数都是经过网络进行 DNS 解析。其中最主要的一个方法就是: dsn.resolve()
。网络
const dns = require('dns');
dns.resolve('ahonn.me', (err, records) => {
if (err) {
throw err;
}
console.log(records);
});
// [ '151.101.100.133' ]
复制代码
该方法经过二个参数能够指定解析的资源记录类型,默认为 ’A’,即返回 IPv4 地址。若是想返回全部的资源纪录类型的值,能够经过 dns.resolveAny()
来获取。并发
const dns = require('dns');
dns.resolveAny('ahonn.me', (err, records) => {
if (err) {
throw err;
}
console.log(records);
});
/* [ { address: '151.101.100.133', ttl: 369, type: 'A' }, { value: 'dns10.hichina.com', type: 'NS' }, { value: 'dns9.hichina.com', type: 'NS' }, { entries: [ 'google-site-verification=j5dWC85DkoAfUR50W00ewfii3X9ouH55HnyBP6oZxGE' ], type: 'TXT' }, { nsname: 'dns9.hichina.com', hostmaster: 'hostmaster.hichina.com', serial: 2015090709, refresh: 3600, retry: 1200, expire: 3600, minttl: 360, type: 'SOA' }] */
复制代码
与此同时,模块还提供了一些与资源记录类型绑定的函数,用于单独获取某资源记录类型的值。例如 dns.resolve4()
,dns.resolve6()
与dns.resolveCname()
等。函数
通常状况下咱们所说的 DNS 解析指的是正向解析,即经过域名查询 IP 地址。那么既然有正向解析就必然有反向解析了(rDNS)。dns 模块中一样提供了方法来进行反向查询,经过 IP 地址查找对应的域名。高并发
dns.resolve('google.com', (err, addresses) => {
if (err) {
throw err;
}
addresses.map(ip => {
dns.reverse(ip, (err, hostnames) => {
if (err) {
throw err;
}
console.log(ip, hostnames);
});
})
});
复制代码
TIPS: 在命令行中咱们能够经过
nslookup -qt=ptr <IP>
来查看该 IP 地址反向解析的结果信息。
还须要注意的是大多数 IP 地址都没有作反向域名解析,设置反向解析须要找对应的服务器 IP 提供商进行设置。如何为服务器 IP 地址添加反向解析可参考这篇文章:为服务器IP添加反向DNS解析 | 祁劲松的博客👨💻。
反向解析主要应用到邮件服务器中来阻拦垃圾邮件,若邮件发送者的 IP 地址没有设置反向解析则将其视为垃圾邮件。
默认状况下 DNS 服务器的 IP 地址是由网关进行分配的,但咱们也能够设置为咱们想使用的 IP 地址。比较有名的是国内通用的 114.114.114.114 以及 Google 的 8.8.8.8。
Dns 模块能够经过 dns.setServers()来设置模块使用哪些 DNS 服务器进行解析。例如咱们将 dns 模块使用的 DNS 服务器设置为 8.8.8.8。
const dns = require('dns');
dns.setServers(['8.8.8.8']);
dns.resolove('ahonn.me', (err, records) => {
if (err) {
throw err;
}
console.log(records);
});
复制代码
另外咱们也能够经过 dns.Resolver()进行独立的设置 DNS 服务器 IP 地址,这样就不会影响 dns 模块的默认 DNS 服务器配置。 dns.Resolver() 的实例拥有与 dns 模块相同的 lookup, resolve等方法。
const { Resolver } = require('dns');
const resolver = new Resolver();
resolver.setServers(['8.8.8.8']);
reslover.reslove('ahonn.me', (err, records) => {
if (err) {
throw err;
}
console.log(records);
});
复制代码
经过 dns 模块中的反向解析能够判断是否为垃圾邮件以外,正向解析能够定时向指定的 DNS 服务发送请求进行 DNS 解析,用来确认当前是否链接到网络(网络断开的状况下必然是没有办法经过网络进行 DNS 解析)。
const { Resolver } = require('dns');
function internetAvailable() {
const resolver = new Resolver();
resolver.setServers(['8.8.8.8']);
reslover.reslove('google.com', (err) => {
if (err) {
reject(err);
} else {
resolve();
}
});
}
复制代码