你可能不知道的 Node.js DNS 模块

首发于个人博客: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缓存

dns.lookup(hostname[, options], callback)

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()网络

dns.resolve(hostname[, rrtype], callback)

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() 来获取。并发

dns.resolveAny(hostname, callback)

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.reverse(ip, callback)

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 服务器

默认状况下 DNS 服务器的 IP 地址是由网关进行分配的,但咱们也能够设置为咱们想使用的 IP 地址。比较有名的是国内通用的 114.114.114.114 以及 Google 的 8.8.8.8。

dns.setServers(servers)

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.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();
	  }
  });
}
复制代码

参考资料

相关文章
相关标签/搜索