Node.js API详解之 dns模块用法实例分析


Posted in Javascript onMay 15, 2020

本文实例讲述了Node.js API详解之 dns模块用法。分享给大家供大家参考,具体如下:

Node.js API详解之 dns

dns (域名服务器)模块包含两类函数:

第一类函数,使用底层操作系统工具进行域名解析,且无需进行网络通信。 这类函数只有一个:dns.lookup()。

例子,查找 baidu.com:

const dns = require('dns');
dns.lookup('www.baidu.com', (err, address, family) => {
 console.log('IP 地址: %j 地址族: IPv%s', address, family);
});
// IP 地址: "180.149.131.98" 地址族: IPv4

第二类函数,连接到一个真实的 DNS 服务器进行域名解析,且始终使用网络进行 DNS 查询。
这类函数包含了 dns 模块中除 dns.lookup() 以外的所有函数。
这些函数使用与 dns.lookup() 不同的配置文件(例如 /etc/hosts)。
这类函数适合于那些不想使用底层操作系统工具进行域名解析、而是想使用网络进行 DNS 查询的开发者。

例子,解析 ‘archive.org' 然后逆向解析返回的 IP 地址:

const dns = require('dns');
dns.resolve4('archive.org', (err, addresses) => {
 if (err) throw err;
 console.log(`IP 地址: ${JSON.stringify(addresses)}`);
 addresses.forEach((a) => {
  dns.reverse(a, (err, hostnames) => {
   if (err) {
    throw err;
   }
   console.log(`IP 地址 ${a} 逆向解析到域名: ${JSON.stringify(hostnames)}`);
  });
 });
});
// IP 地址: ["207.241.224.2"]
// IP 地址 207.241.224.2 逆向解析到域名: ["www.archive.org"]

dns.getServers()

说明:

返回一个用于当前DNF解析的IP地址的数组的字符串,格式根据rfc5952。
如果使用自定义端口,那么字符串将包括一个端口部分。

demo:

const dns= require('dns');
console.log( dns.getServers() );
// [ '172.116.20.254', '127.0.0.1' ]

dns.setServers(servers)

说明:

设置IP地址服务器端口在进行DNS解析时可用,servers参数是一个rfc5952数组格式的地址。
如果端口是IANA默认端口(53),那么它可以被忽略。

demo:

const dns = require('dns');
dns.setServers([ '172.116.20.254', '127.1.1.1' ])
console.log( dns.getServers() );
// [ '172.116.20.254', '127.1.1.1' ]

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

说明:

解析hostname(例如:'nodejs.org')第一个找到的A(IPv4)或AAAA(IPv6)记录。
options可以是对象或者整数。如果options没有被提供,那么IPv4 和 IPv6都是有效的。如果options是整数,只能是4或6。
另外,options可以是一个含有以下属性的对象:
family: T地址族。如果提供,必须为整数4或6。如果没有提供,只接受IPv4和IPv6地址。
all:值为true时, 回调函数返回一个包含所有解析后地址的数组,否则只返回一个地址。默认值为false
hints:如果提供,它必须是一个或多个支持的getaddrinfo标识。如果没有提供,那么没有标识被传递给getaddrinfo。
多个标识可以通过在逻辑上ORing它们的值,来传递给hints。支持的getaddrinfo标识:
dns.ADDRCONFIG: 返回当前系统支持的地址类型。例如,如果当前系统至少配置了一个 IPv4 地址,则返回 IPv4地址。不考虑回环地址。
dns.V4MAPPED: 如果指定了 IPv6 家族, 但是没有找到 IPv6 地址,将返回 IPv4 映射的 IPv6地址。在有些操作系统中不支持(e.g FreeBSD 10.1)。
回调函数包含(err, address, family)参数。
address是IPv4或IPv6地址字符串。
family、是整数4或6,表示地址族(不一定是最初传递给查找的值)。
当all属性被设置为true时,回调函数参数变为(err, addresses),addresses则变成一个由address 和 family 属性组成的对象数组。
dns.lookup() 不需要与DNS协议有任何关系。它仅仅是一个连接名字和地址的操作系统功能。
在任何的node.js程序中,它的实现对表现有一些微妙但是重要的影响。
尽管dns.lookup()和各种dns.resolve *()/ dns.reverse()函数有相同的目标将网络的名字与网络地址联系在一起(反之亦然),
他们的行为是完全不同的。 这些差异可以有微妙但重大影响着Node.js程序行为。

demo:

const dns = require('dns');
const options = {
  family: 6,
  hints: dns.ADDRCONFIG | dns.V4MAPPED,
};
dns.lookup('nodejs.cn', options, (err, address, family) =>
  console.log('address: %j family: IPv%s', address, family));
// address: "::ffff:112.124.39.54" family: IPv6
options.all = true;
dns.lookup('nodejs.cn', options, (err, addresses) =>
  console.log('addresses: %j', addresses));
// addresses: [{"address":"::ffff:112.124.39.54","family":6}]

dns.lookupService(address, port, callback)

说明:

将参数address和port传入操作系统底层getnameinfo服务来解析处理并返回主机名。
如果address不是有效的IP地址,会抛出TypeError。port必须是一个整数.如果不是规定的端口号,会抛出TypeError.
出错情况下,err是一个Error对象,err.code代码错误码。

demo:

const dns = require('dns');
dns.lookupService('127.0.0.1', 22, (err, hostname, service) => {
 console.log(hostname, service);
 // localhost ssh
});

dns.reverse(ip, callback)

说明:

执行一个反向DNS查询返回IPv4或IPv6地址的主机名的数组。

demo:

const dns = require('dns');
dns.reverse('101.20.17.16', (err, hostname) => {
 console.log(hostname);
});

dns.Resolver 类

说明:

DNS请求的独立解析程序。
使用默认的设置创建一个新的解析程序。
为一个解析程序设置servers使用resolver.setServers(),它不会影响其他的解析程序:

demo:

const { Resolver } = require('dns');
const resolver = new Resolver();
resolver.setServers(['4.4.4.4']);
resolver.resolve4('baidu.com', (err, addresses) => {
 console.log(addresses);
});

resolver.cancel()

说明:

取消这个解析程序的未解决的DNS查询,相应的回调用一个ECANCELLED码调用。

demo:

const { Resolver } = require('dns');
const resolver = new Resolver();
resolver.setServers(['4.4.4.4']);
resolver.resolve4('baidu.com', (err, addresses) => {
 console.log(addresses);
});
resolver.cancel();

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

说明:

hostname:解析的主机名。
rrtype:资源记录类型. 默认: ‘A'.c
使用DNS协议来解析一个主机名(e.g. ‘nodejs.org')为一个资源记录的数组。
回调函数的参数为(err, records)。当成功时,records将是一个资源记录的数组。它的类型和结构取决于rrtype。
下面是不同rrtype对应resolve的快捷方法:

Node.js API详解之 dns模块用法实例分析

demo:

const dns = require('dns');
dns.resolve('archive.org', 'A', (err, addresses) => {
 if (err) throw err;
 console.log(`IP 地址: ${JSON.stringify(addresses)}`);
});
// IP 地址: ["207.241.224.2"]

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

说明:

使用DNS协议解析IPv4地址主机名(A记录)。
adresses参数是传递给callback函数的IPv4地址数组。(例如:[‘74.125.79.104', ‘74.125.79.105', ‘74.125.79.106'])
hostname:需要解析的主机名
options.ttl:记录每一条记录的存活次数 (TTL)。如果为 true, 返回的结果将会为 Object 的数组,就像 { address: ‘1.2.3.4', ttl: 60 } 带有 TTL 秒数的记录,而不是 string 的数组.

demo:

const dns = require('dns');
dns.resolve4('archive.org', {ttl: true}, (err, addresses) => {
 if (err) throw err;
 console.log(`IPv4地址数组: ${JSON.stringify(addresses)}`);
});
// IPv4地址数组: [{"address":"207.241.224.2","ttl":58}]

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

说明:

使用DNS协议解析IPv6地址主机名(AAAA记录)。
adresses参数是传递给callback函数的IPv6地址数组.

demo:

const dns = require('dns');
dns.resolve6('www.taobao.com', {ttl: true}, (err, addresses) => {
 if (err) throw err;
 console.log(`IPv6地址主机名: ${JSON.stringify(addresses)}`);
});
// IPv6地址主机名: []

dns.resolveCname(hostname, callback)

说明:

使用DNS协议解析CNAME记录主机名。
adresses参数是传递给callback函数规范内有效的主机名数组(例如:[‘bar.example.com']).

demo:

const dns = require('dns');
dns.resolveCname('www.taobao.com', (err, addresses) => {
 if (err) throw err;
 console.log(`CNAME记录主机名: ${JSON.stringify(addresses)}`);
});
// CNAME记录主机名: ["www.taobao.com.danuoyi.tbcache.com"]

dns.resolveMx(hostname, callback)

说明:

使用DNS协议处理邮件交换记录主机名(MX记录)。
adresses参数是传递给callback函数的主机名对象数组,对
象包含priority和exchange属性(例如: [{priority: 10, exchange: ‘mx.example.com'}, …])。

demo:

const dns = require('dns');
dns.resolveMx('mail.qq.com', (err, addresses) => {
 if (err) throw err;
 console.log(`MX记录: ${JSON.stringify(addresses)}`);
});

dns.resolveNaptr(hostname, callback)

说明:

使用DNS协议来处理基于正则表达式匹配的记录(NAPTR记录)的主机名。
adresses参数是传递给callback函数的主机名对象数组,对象包含属性:
flags
service
regexp
replacement
order
preference

demo:

const dns = require('dns');
dns.resolveNaptr('www.taobao.com', (err, addresses) => {
 if (err) throw err;
 
 console.log(`NAPTR记录: ${JSON.stringify(addresses)}`);
});

dns.resolveNs(hostname, callback)

说明:

使用DNS协议处理名称服务器主机名记录(NS记录)。
adresses为有效的名称服务器记录主机名数组(eg:[‘ns1.example.com', ‘ns2.example.com'])。

demo:

const dns = require('dns');
dns.resolveNs('www.taobao.com', (err, addresses) => {
 if (err) throw err;
 console.log(`NS记录: ${JSON.stringify(addresses)}`);
});

dns.resolvePtr(hostname, callback)

说明:

使用DNS协议处理主机名引用记录(PTR记录)。
addresses参数将一个字符串数组传递给回调函数callback,其中包含回复记录。

demo:

const dns = require('dns');
dns.resolvePtr('www.taobao.com', (err, addresses) => {
 if (err) throw err;
 
 console.log(`PTR记录: ${JSON.stringify(addresses)}`);
});

dns.resolveSoa(hostname, callback)

说明:

使用DNS协议处理主机名子域名记录(SOA记录)。addresses参数为一个对象包含以下属性:
nsname
hostmaster
serial
refresh
retry
expire
minttl

demo:

const dns = require('dns');
dns.resolveSoa('www.taobao.com', (err, addresses) => {
 if (err) throw err;
 
 console.log(`SOA记录: ${JSON.stringify(addresses)}`);
});

dns.resolveSrv(hostname, callback)

说明:

使用DNS协议来处理主机名服务记录(SRV记录)。
callback函数返回的addresses参数为对象数组,每个对象包含以下属性:
priority
weight
port
name

demo:

const dns = require('dns');
dns.resolveSrv('www.taobao.com', (err, addresses) => {
 if (err) throw err;
 console.log(`SRV记录: ${JSON.stringify(addresses)}`);
});

dns.resolveTxt(hostname, callback)

说明:

使用DNS协议处理文本查询主机名(TXT记录)。回调函数callback会返回records参数,
它是一个文本记录与主机名一一对应的二维数组(例如:[ [‘v=spf1 ip4:0.0.0.0 ‘, ‘~all' ] ]).
每个数组文本块包含一条记录。根据用例,这些可以是连接在一起或单独对待。

demo:

const dns = require('dns');
dns.resolveTxt('www.taobao.com', (err, addresses) => {
 if (err) throw err;
 
 console.log(`TXT记录: ${JSON.stringify(addresses)}`);
});

dns.resolveAny(hostname, callback)

说明:

使用DNS协议解析所有记录。
callback函数的参数将是一个包含各种类型记录的数组。每个对象都有一个属性type,指示当前记录的类型。
“A”、”AAAA”、”CNAME”、”MX”、”NAPTR”、”NS”、”PTR”、”SOA”、”SRV”、”TXT”等

demo:

const dns = require('dns');
dns.resolveAny('www.taobao.com', (err, addresses) => {
 if (err) throw err;
 console.log(`${JSON.stringify(addresses)}`);
});
// [ { type: 'A', address: '127.0.0.1', ttl: 299 },
//  { type: 'CNAME', value: 'example.com' },
//  { type: 'MX', exchange: 'alt4.aspmx.l.example.com', priority: 50 },
//  { type: 'NS', value: 'ns1.example.com' },
//  { type: 'TXT', entries: [ 'v=spf1 include:_spf.example.com ~all' ] },
//  { type: 'SOA',
//   nsname: 'ns1.example.com',
//   hostmaster: 'admin.example.com',
//   serial: 156696742,
//   refresh: 900,
//   retry: 900,
//   expire: 1800,
//   minttl: 60 } ]

错误码

说明:

每个DNS查询可以返回一个错误代码如下:
dns.NODATA:DNS服务返回没有数据。
dns.FORMERR:DNS服务器查询没有格式化。
dns.SERVFAIL:DNS服务器返回失败。
dns.NOTFOUND:域名未找到。
dns.NOIMP:DNS服务器不执行请求的操作。
dns.REFUSED:查询DNS服务器拒绝。
dns.BADQUERY:未格式化DNS查询。
dns.BADNAME:未格式化主机名
dns.BADFAMILY:没有提供地址族
dns.BADRESP:未格式化DNS回复
dns.CONNREFUSED:无法连接DNS服务器
dns.TIMEOUT:连接DNS服务器超时
dns.EOF:文件末尾
dns.FILE:读取文件错误
dns.NOMEM:内存溢出
dns.DESTRUCTION:通道以及销毁
dns.BADSTR:未格式化字符串
dns.BADFLAGS:指定非法标记
dns.NONAME:给定的主机名不是数字。
dns.BADHINTS:指定非法的提示标志。
dns.NOTINITIALIZED:c-ares异步DNS请求库初始化未完成。
dns.LOADIPHLPAPI:加载iphlpapi.dll(Windows IP辅助API应用程序接口模块)错误
dns.ADDRGETNETWORKPARAMS:找不到GetNetworkParams(读取本机DNS信息)函数
dns.CANCELLED:DNS查询取消

dns.lookup() 与 dns.resolve(), dns.resolve*() and dns.reverse()

说明:

在底层,dns.lookup()使用操作系统设施与大多数其他程序相同。
例如,dns.lookup()几乎总是解析给定的主机名与ping命令一样。
在许多类POSIX操作系统中, dns.lookup()函数的行为可以通过改变nsswitch.conf(5)并且/或resolv.conf(5)设置进行改变,
但是需要注意改变这些文件就意味着改变所有正在这个操作系统中运行 的所有进程的行为。
尽管以异步JavaScript的角度来调用dns.lookup(),但在内部libuv底层线程池中却是同步的调用getaddrinfo(3)
dns.resolve(), dns.resolve*() and dns.reverse()这些功能实现与dns.lookup()截然不同。
它们不仅没有使用getaddrinfo(3)并且通过网络执行DNS查询。使用异步网络通信,并且没有使用libuv线程池。
因此,这些函数不会像使用libuv线程池的dns.lookup()函数一样会对其它进程有负面影响。
它们不像dns.lookup()一样使用相同的配置文件。例如,它们不会使用来自/etc/hosts配置。

希望本文所述对大家node.js程序设计有所帮助。

Javascript 相关文章推荐
JS启动应用程序的一个简单例子
May 11 Javascript
js 模拟气泡屏保效果代码
Jul 10 Javascript
js数值计算时使用parseInt进行数据类型转换(jquery)
Oct 07 Javascript
node.js中的path.basename方法使用说明
Dec 09 Javascript
jQuery类选择器用法实例
Dec 23 Javascript
JS获取及设置TextArea或input文本框选择文本位置的方法
Mar 24 Javascript
12306验证码破解思路分享
Mar 25 Javascript
jQuery validate插件submitHandler提交导致死循环解决方法
Jan 21 Javascript
js仿3366小游戏选字游戏
Apr 14 Javascript
微信小程序下拉框功能的实例代码
Nov 06 Javascript
vue微信分享出来的链接点开是首页问题的解决方法
Nov 28 Javascript
JavaScript实现简单轮播图效果
Dec 01 Javascript
关于vue3默认把所有onSomething当作v-on事件绑定的思考
May 15 #Javascript
js实现简单贪吃蛇游戏
May 15 #Javascript
Javascript执行流程细节原理解析
May 14 #Javascript
使用npm命令提示: 'npm' 不是内部或外部命令,也不是可运行的程序的处理方法
May 14 #Javascript
javascript中的offsetWidth、clientWidth、innerWidth及相关属性方法
May 14 #Javascript
vue组件系列之TagsInput详解
May 14 #Javascript
ant-design-vue按需加载的坑的解决
May 14 #Javascript
You might like
php使用memcoder将视频转成mp4格式的方法
2015/03/12 PHP
使用PHP编写发红包程序
2015/07/22 PHP
PHP魔术方法之__call与__callStatic使用方法
2017/07/23 PHP
php无限级评论嵌套实现代码
2018/04/18 PHP
laravel项目利用twemproxy部署redis集群的完整步骤
2018/05/11 PHP
php用wangeditor3实现图片上传功能
2019/08/22 PHP
Extjs4 GridPanel 的几种样式使用介绍
2013/04/18 Javascript
JS定时器实例详细分析
2013/10/11 Javascript
jQuery带进度条全屏图片轮播特效代码分享
2020/06/28 Javascript
JavaScript中三种异步上传文件方式
2016/03/06 Javascript
js和C# 时间日期格式转换的简单实例
2016/05/28 Javascript
js数组操作方法总结(必看篇)
2016/11/22 Javascript
JavaScript正则获取地址栏中参数的方法
2017/03/02 Javascript
鼠标经过出现气泡框的简单实例
2017/03/17 Javascript
详解Vue-Cli 异步加载数据的一些注意点
2017/08/12 Javascript
解决Vue编译时写在style中的路径问题
2017/09/21 Javascript
Bootstrap实现翻页效果
2017/11/27 Javascript
js原生方法被覆盖,从新赋值原生的方法
2018/01/02 Javascript
浅谈SpringMVC中post checkbox 多选框value的值(隐藏域方式)
2018/01/08 Javascript
代码分析vue中如何配置less
2018/09/28 Javascript
Element-UI中关于table表格的那些骚操作(小结)
2019/08/15 Javascript
python追加元素到列表的方法
2015/07/28 Python
Python GUI Tkinter简单实现个性签名设计
2018/06/19 Python
基于Python对数据shape的常见操作详解
2018/12/25 Python
pandas dataframe添加表格框线输出的方法
2019/02/08 Python
在Pandas中处理NaN值的方法
2019/06/25 Python
Python列表操作方法详解
2020/02/09 Python
Under Armour西班牙官网:美国知名的高端功能性运动品牌
2018/12/12 全球购物
彪马俄罗斯官网:PUMA俄罗斯
2019/07/13 全球购物
校园自助餐厅的创业计划书
2013/12/26 职场文书
2014年学生会主席工作总结
2014/11/07 职场文书
大班下学期个人总结
2015/02/13 职场文书
幼儿园中班教学反思
2016/03/03 职场文书
MySQL如何使备份得数据保持一致
2022/05/02 MySQL
kubernetes集群搭建Zabbix监控平台的详细过程
2022/07/07 Servers
ubuntu开机后ROS程序自启动问题
2022/12/24 Servers