www.bifa88.com 3

js中DNS模块学习总计

1. DNS

Node.js中DNS模块学习总结,node.jsdns

1. DNS

在Node.js中,提供DNS模块,以实现域名查找及域名解析的处理。

  • 在DNS模块中,提供了三个主方法及一系列便捷方法。
  • resolve方法:用于将一个域名解析为一组DNS记录。
  • reverse方法: 用于将IP地址转换为一组域名。
  • lookup方法: 用于将一个域名转换成IP地址。
  • DNS模块中的其余便捷方法均为resolve方法的一种便捷形式。

2. 使用resolve方法将域名解析为DNS记录

`DNS.resolve(domain, [rrtype], callback(err, address){…})`

domain参数为一个字符串,用于指定需要被解析的域名,可以包括子域名。
rrtypr参数为一个字符串,用于指定需要获取的记录类型,可指定的记录类型如下。

  • A,该参数值为默认值,当记录类型为A时,该记录将一个IPv4地址映射为一个域名。
  • AAAA,当记录类型为AAAA时,该记录将一个IPv6地址映射为一个域名。
  • CNAME,当记录类型为CNAME时,表示该记录为一个域名的别名记录,例如,一个www.example.com域名记录也许为一个example.com域名记录额别名记录。
  • MX,MX记录指向一个使用SMTP的域中的邮件服务器,例如,当你想[email protected]邮件地址发送电子邮件时,domain.com域的MX记录中保存了发送该邮件时的邮件服务器地址。
  • TXT,TXT记录是为该域名附加的描述记录。
  • SRV,SRV记录用于为一个特定域中所有可用服务提供信息。
  • PTR,PTR记录用于反向地址解析,该记录将一个域名映射为一个IPv4地址。
  • NS,NS(Name
    Server)记录是域名服务器记录,用来指定该域名由哪个DNS服务器进行解析。

回调函数有两个参数,err是域名解析失败时触发的错误对象,addresses参数为一个数组,其中存放了所有获取到的DNS记录。

3. 为resolve方法定制的各种便捷方法

  • DNS.resolve4(domain, callback),获取IPv4地址
  • DNS.resolve6(domain, callback),获取IPv6地址
  • DNS.resolveMx(domain, callback),获取MX记录,邮件交换服务器记录
  • DNS.resolveTxt(domain, callback),获取TXT记录,域名附加的描述记录
  • DNS.resolveSrv(domain, callback),获取SRV记录,服务记录
  • DNS.resolveNs(domain, callback),获取NS记录,域名服务器记录
  • DNS.resolveCname(domain, callback),获取别名记录

4. 使用lookup方法查询IP地址

当使用resolve4方法或者resolve6方法时,由于callback参数值回调函数中的addresses参数值数组中存放着所有获取到的IPv4地址或IPv6地址。因此DNS模块中提供了一个获取第一个被发现的IPv4地址或者IPv6地址的lookup方法

`DNS.lookup(domain, [family], callback(err, addresses,
family){…})`

  • domain参数为一个字符串,用于指定需要解析的域名
  • family参数值为一个整数值,用于指定需要获取的IP地址类型,可指定的参数值为4或6,默认参数值为null,表示既可以获取IPv4,又可以获取IPv6
  • 回调函数err参数值为获取地址失败时触发的错误对象,当域名不存在或查询失败时该错误对象的code属性值为ENOENT
  • addresses参数值为一个字符串,为获取到的IP地址
  • family参数值为4时,表示为一个IPv4地址,为6时,表示为一个IPv6地址。

5. 使用reverse方法反向解析IP地址

在DNS模块中,使用reverse方法将一个IP地址反向解析为一组与该IP地址绑定的域名

`DNS.reverse(ip, callback(err, domains){…})`

  • ip参数值为一个字符串,用于指定需要解析的IP地址
  • 回调函数的err为反向解析地址失败后的错误对象
  • domains参数值为一个数组,存放了所有获取到的域名

6. DNS模块中的各种错误代码

err参数值为执行各种解析或反向解析操作时触发的错误对象,可根据该错误对象的code属性值,即触发的错误代号判断出发了什么错误

  • ENODATA:DNS服务器返回一个没有数据的查询结果
  • EFORMERR:DNS服务器发现客户端请求查询时使用了格式错误的查询参数
  • ESERVFAIL:DNS服务器执行查询操作失败
  • ENOTFOUND:未发现任何域名
  • ENOTIMP:DNS服务器不能进行客户端所请求的查询操作
  • EREFUSED:DNS服务器拒绝进行查询操作
  • EBADQUERY:格式错误的DNS查询
  • EBADNAME:域名格式错误
  • EBADFAMILY:不支持的IP地址类型
  • EBADRESP:DNS答复的格式错误
  • ECONNREFUSED:不能建立与DNS服务器之间的连接
  • ETIMEOUT:与DNS服务器之间建立连接超时
  • EEOF:已到达文件底部
  • EFILE:读取文件失败
  • ENOMEM:没有足够的内存空间
  • EDESTRUCTION:通道已经被销毁
  • EBADSTR:字符串格式错误
  • EBADFLAGS:指定了错误的判断标志
  • ENONAME:指定的主机名不是数值格式的
  • EBADHINTS:指定的提示标志无效
  • ENOTINITIALIZED:c-ares类库初始化工作尚未完成
  • ELOADIPHLPAPI:加载iphlpapi.dll时触发了一个错误
  • EADDREGETNETWORKPARAMS:未发现GetNetworkParams函数
  • ECANCELLED:DNS查询操作被取消

7. DNS模块的基本使用

const dns = require('dns');
let url = 'www.qq.com';

dns.resolve(url, 'A', (err, addresses) => {
  console.log(addresses);
  // IPv4地址 [ '103.7.30.123' ]
});

dns.resolve(url, 'AAAA', (err, addresses) => {
  console.log(addresses);
  // IPv6地址 [ '240e:e1:8100:28::2:16' ]
});
dns.resolveMx('qq.com', (err, addresses) => {
  console.log(addresses);
  // 邮件交换服务器记录
  // [ { exchange: 'mx2.qq.com', priority: 20 },
  //  { exchange: 'mx1.qq.com', priority: 30 },
  //  { exchange: 'mx3.qq.com', priority: 10 } ]

});

dns.resolveTxt('qq.com', (err, addresses) => {
  console.log(addresses);
  // 域名附加的描述记录
  // [ [ 'v=spf1 include:spf.mail.qq.com -all' ] ]
});

dns.resolveSrv('www.baidu.com', (err, addresses) => {
  console.log(addresses);
  // 服务记录
  // []
});

dns.resolveNs('www.github.com', (err, addresses) => {
  console.log(addresses);
  // 域名服务器记录
  // [ 'ns-421.awsdns-52.com',
  // 'ns-520.awsdns-01.net',
  // 'ns1.p16.dynect.net',
  // 'ns2.p16.dynect.net',
  // 'ns3.p16.dynect.net',
  // 'ns4.p16.dynect.net',
  // 'ns-1283.awsdns-32.org',
  // 'ns-1707.awsdns-21.co.uk' ]
});

dns.resolveCname('www.163.com', (err, addresses) => {
  console.log(addresses);
  // 获取别名记录
  // [ 'www.163.com.lxdns.com' ]
});


dns.lookup('google.com', 4, (err, address, family) => {
  // 查询IP地址
  // address,查询到的地址
  // family,IPv4或IPv6
  console.log(address);// 172.217.27.142
  console.log(family);// 4
});

dns.lookup('google.com', 6, (err, address, family) => {
  console.log(address);// 2404:6800:4008:803::200e
  console.log(family);// 6
});

dns.reverse('203.188.200.67', (err, domain) => {
  // 反向解析IP地址
  console.log(domain);
  // [ 'media-router-fp1.prod.media.vip.tp2.yahoo.com' ]
});

1. DNS
在Node.js中,提供DNS模块,以实现域名查找及域名解析的处理。
在DNS模块中,提供了三个主方法及一…

前面的话

  本文将详细介绍域名解析模块DNS

 

在Node.js中,提供DNS模块,以实现域名查找及域名解析的处理。

工作原理

  打开浏览器,在上方地址栏输入网址的那一刻,这个回车按了之后,发生了很多事情。首先,计算机只懂0和1,也就是说人类的字母网址计算机是不懂的,它只认识IP地址,如果是IPV4那就是4组8位的二进制数字。为了人类方便,需要有一个把网址翻译成IP地址的服务,就是DNS

  DNS整个获取过程是被层层缓存的

www.bifa88.com 1

  1、浏览器搜索自身的DNS缓存

  浏览器DNS缓存的时间跟DNS服务器返回的TTL值无关。

  浏览器在获取网站域名的实际IP地址后会对其IP进行缓存,减少网络请求的损耗。每种浏览器都有一个固定的DNS缓存时间,其中Chrome的过期时间是1分钟,在这个期限内不会重新请求DNS

  Chrome浏览器看本身的DNS缓存时间比较方便,在地址栏输入

chrome://net-internals/#dns

www.bifa88.com 2

  2、搜索操作系统自身的DNS缓存 

  3、读取本地的HOST文件,Windows下路径一般为

c:\Windows\System32\drivers\etc\hosts

www.bifa88.com 3

  4、向宽带运营商ISP发起一个DNS的系统调用,ISP服务器查看本身缓存

  5、如果还没有找到,ISP服务器会代替本地计算机发起一个迭代DNS解析的请求

  6、如果仍然不成功,则解析失败

 

  • 在DNS模块中,提供了三个主方法及一系列便捷方法。
  • resolve方法:用于将一个域名解析为一组DNS记录。
  • reverse方法: 用于将IP地址转换为一组域名。
  • lookup方法: 用于将一个域名转换成IP地址。
  • DNS模块中的其余便捷方法均为resolve方法的一种便捷形式。

本地解析

  dns模块包含两个类型的函数,其中一种是使用底层操作系统工具进行域名解析的函数,并不须要进行网络通信。这类函数只有一个:dns.lookup()

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

  该方法将域名(比如’cnblogs.com’)解析为第一条找到的记录 A (IPV4)或
AAAA(IPV6)。参数 options可以是一个对象或整数。如果没有提供 options,IP
v4 和 v6 地址都可以。如果 options 是整数,则必须是 4 或 6

  options参数包含以下属性

family:地址协议族,必须为4或6的整数
hints:设置getaddrinfo的标志,dns.ADDRCONFIG 或者 dns.V4MAPPED(ipv4映射成ipv6)
all:false(默认),布尔值,如设置为true,则返回IP数组,否则返回单个IP地址

{
  family: 4,
  hints: dns.ADDRCONFIG | dns.V4MAPPED
}

  回调函数包含参数 (err, address, family)。 address参数表示 IP v4 或
v6 地址。family 参数是4 或 6,表示 address 家族(不一定是之前传入 lookup
的值)。出错时,参数 err 是 Error 对象,err.code是错误代码

  [注意]err.code等于’ENOENT’,可能是因为域名不存在,还有可能是其他原因,如没有可用文件描述符

var dns = require('dns');
dns.lookup('www.cnblogs.com', function(err, address, family){
    console.log(err);//null
    console.log(address);//218.11.2.249
    console.log(family);//4
});

  同一个域名,可能对应多个不同的ip。可以通过设置options = {all:
true}来获取

var dns = require('dns');
dns.lookup('www.qq.com',{all:true}, function(err, address, family){
    console.log(err);//null
/*
[ { address: '125.39.240.113', family: 4 },
  { address: '61.135.157.156', family: 4 } ]
 */
    console.log(address);
    console.log(family);//undefined
});

【dns.lookupService(address, port, callback)】

  与lookup相对应,lookupService()方法进行从ip地址和端口到域名的反向解析

  该方法的回调函数的参数是 (err, hostname, service)。 hostname 和
service 都是字符串 (比如 ‘localhost’ 和 ‘http’)。出错时,参数err 是
Error 对象,err.code是错误代码

var dns = require('dns');
dns.lookupService('127.0.0.1',80,function(err, hostname, service){
    console.log(err);//null
    console.log(hostname);//bai
    console.log(service);//http
});

 

2. 使用resolve方法将域名解析为DNS记录

网络解析

  除dns.lookup()以外的所有dns模块中的函数,都需要连接到实际DNS服务器进行域名解析的函数,并且始终使用网络执行DNS查询

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

  该方法将一个域名(如 ‘cnblogs.com’)解析为一个 rrtype
指定记录类型的数组

  有效的 rrtypes 值为:

'A' (IPV4 地址, 默认)
'AAAA' (IPV6 地址)
'MX' (邮件交换记录)
'TXT' (text 记录)
'SRV' (SRV 记录)
'PTR' (用来反向 IP 查找)
'NS' (域名服务器 记录)
'CNAME' (别名 记录)
'SOA' (授权记录的初始值)

  回调参数为 (err, addresses).
其中 addresses 中每一项的类型都取决于记录类型。出错时,参数err 是 Error 对象,err.code是错误代码

var dns = require('dns');
//IPV4
dns.resolve('www.qq.com',function(err,address){
    console.log(address);//[ '125.39.240.113', '61.135.157.156' ]
});

//IPV6
dns.resolve('www.qq.com','AAAA',function(err,address){
    console.log(address);//[ '240e:e1:8100:28::2:16' ]
});

//别名
dns.resolve('www.qq.com','CNAME',function(err,address){
    console.log(address);//undefined
});

【dns.resolve4(hostname, callback)】

  和 dns.resolve() 类似,仅能查询 IPv4 (A 记录)

var dns = require('dns');
dns.resolve4('www.qq.com',function(err,address){
    console.log(address);//[ '125.39.240.113', '61.135.157.156' ]
});

【dns.reverse(ip, callback)】

  该方法用于反向解析 IP 地址,返回指向该 IP
地址的域名数组。回调函数参数 (err, hostnames)。出错时,参数err 是 Error
对象,err.code是错误代码

var dns = require('dns');
dns.reverse('114.114.114.114',function(err,hostnames){
    console.log(hostnames);//'public1.114dns.com'
});

 

`DNS.resolve(domain, [rrtype], callback(err, address){…})`

domain参数为一个字符串,用于指定需要被解析的域名,可以包括子域名。
rrtypr参数为一个字符串,用于指定需要获取的记录类型,可指定的记录类型如下。

  • A,该参数值为默认值,当记录类型为A时,该记录将一个IPv4地址映射为一个域名。
  • AAAA,当记录类型为AAAA时,该记录将一个IPv6地址映射为一个域名。
  • CNAME,当记录类型为CNAME时,表示该记录为一个域名的别名记录,例如,一个www.example.com域名记录也许为一个example.com域名记录额别名记录。
  • MX,MX记录指向一个使用SMTP的域中的邮件服务器,例如,当你想person@domain.com邮件地址发送电子邮件时,domain.com域的MX记录中保存了发送该邮件时的邮件服务器地址。
  • TXT,TXT记录是为该域名附加的描述记录。
  • SRV,SRV记录用于为一个特定域中所有可用服务提供信息。
  • PTR,PTR记录用于反向地址解析,该记录将一个域名映射为一个IPv4地址。
  • NS,NS(Name
    Server)记录是域名服务器记录,用来指定该域名由哪个DNS服务器进行解析。

回调函数有两个参数,err是域名解析失败时触发的错误对象,addresses参数为一个数组,其中存放了所有获取到的DNS记录。

3. 为resolve方法定制的各种便捷方法

  • DNS.resolve4(domain, callback),获取IPv4地址
  • DNS.resolve6(domain, callback),获取IPv6地址
  • DNS.resolveMx(domain, callback),获取MX记录,邮件交换服务器记录
  • DNS.resolveTxt(domain, callback),获取TXT记录,域名附加的描述记录
  • DNS.resolveSrv(domain, callback),获取SRV记录,服务记录
  • DNS.resolveNs(domain, callback),获取NS记录,域名服务器记录
  • DNS.resolveCname(domain, callback),获取别名记录

4. 使用lookup方法查询IP地址

www.bifa88.com,当使用resolve4方法或者resolve6方法时,由于callback参数值回调函数中的addresses参数值数组中存放着所有获取到的IPv4地址或IPv6地址。因此DNS模块中提供了一个获取第一个被发现的IPv4地址或者IPv6地址的lookup方法

`DNS.lookup(domain, [family], callback(err, addresses,
family){…})`

  • domain参数为一个字符串,用于指定需要解析的域名
  • family参数值为一个整数值,用于指定需要获取的IP地址类型,可指定的参数值为4或6,默认参数值为null,表示既可以获取IPv4,又可以获取IPv6
  • 回调函数err参数值为获取地址失败时触发的错误对象,当域名不存在或查询失败时该错误对象的code属性值为ENOENT
  • addresses参数值为一个字符串,为获取到的IP地址
  • family参数值为4时,表示为一个IPv4地址,为6时,表示为一个IPv6地址。

5. 使用reverse方法反向解析IP地址

在DNS模块中,使用reverse方法将一个IP地址反向解析为一组与该IP地址绑定的域名

`DNS.reverse(ip, callback(err, domains){…})`

  • ip参数值为一个字符串,用于指定需要解析的IP地址
  • 回调函数的err为反向解析地址失败后的错误对象
  • domains参数值为一个数组,存放了所有获取到的域名

6. DNS模块中的各种错误代码

err参数值为执行各种解析或反向解析操作时触发的错误对象,可根据该错误对象的code属性值,即触发的错误代号判断出发了什么错误

  • ENODATA:DNS服务器返回一个没有数据的查询结果
  • EFORMERR:DNS服务器发现客户端请求查询时使用了格式错误的查询参数
  • ESERVFAIL:DNS服务器执行查询操作失败
  • ENOTFOUND:未发现任何域名
  • ENOTIMP:DNS服务器不能进行客户端所请求的查询操作
  • EREFUSED:DNS服务器拒绝进行查询操作
  • EBADQUERY:格式错误的DNS查询
  • EBADNAME:域名格式错误
  • EBADFAMILY:不支持的IP地址类型
  • EBADRESP:DNS答复的格式错误
  • ECONNREFUSED:不能建立与DNS服务器之间的连接
  • ETIMEOUT:与DNS服务器之间建立连接超时
  • EEOF:已到达文件底部
  • EFILE:读取文件失败
  • ENOMEM:没有足够的内存空间
  • EDESTRUCTION:通道已经被销毁
  • EBADSTR:字符串格式错误
  • EBADFLAGS:指定了错误的判断标志
  • ENONAME:指定的主机名不是数值格式的
  • EBADHINTS:指定的提示标志无效
  • ENOTINITIALIZED:c-ares类库初始化工作尚未完成
  • ELOADIPHLPAPI:加载iphlpapi.dll时触发了一个错误
  • EADDREGETNETWORKPARAMS:未发现GetNetworkParams函数
  • ECANCELLED:DNS查询操作被取消

7. DNS模块的基本使用

const dns = require('dns');
let url = 'www.qq.com';

dns.resolve(url, 'A', (err, addresses) => {
  console.log(addresses);
  // IPv4地址 [ '103.7.30.123' ]
});

dns.resolve(url, 'AAAA', (err, addresses) => {
  console.log(addresses);
  // IPv6地址 [ '240e:e1:8100:28::2:16' ]
});
dns.resolveMx('qq.com', (err, addresses) => {
  console.log(addresses);
  // 邮件交换服务器记录
  // [ { exchange: 'mx2.qq.com', priority: 20 },
  //  { exchange: 'mx1.qq.com', priority: 30 },
  //  { exchange: 'mx3.qq.com', priority: 10 } ]

});

dns.resolveTxt('qq.com', (err, addresses) => {
  console.log(addresses);
  // 域名附加的描述记录
  // [ [ 'v=spf1 include:spf.mail.qq.com -all' ] ]
});

dns.resolveSrv('www.baidu.com', (err, addresses) => {
  console.log(addresses);
  // 服务记录
  // []
});

dns.resolveNs('www.github.com', (err, addresses) => {
  console.log(addresses);
  // 域名服务器记录
  // [ 'ns-421.awsdns-52.com',
  // 'ns-520.awsdns-01.net',
  // 'ns1.p16.dynect.net',
  // 'ns2.p16.dynect.net',
  // 'ns3.p16.dynect.net',
  // 'ns4.p16.dynect.net',
  // 'ns-1283.awsdns-32.org',
  // 'ns-1707.awsdns-21.co.uk' ]
});

dns.resolveCname('www.163.com', (err, addresses) => {
  console.log(addresses);
  // 获取别名记录
  // [ 'www.163.com.lxdns.com' ]
});


dns.lookup('google.com', 4, (err, address, family) => {
  // 查询IP地址
  // address,查询到的地址
  // family,IPv4或IPv6
  console.log(address);// 172.217.27.142
  console.log(family);// 4
});

dns.lookup('google.com', 6, (err, address, family) => {
  console.log(address);// 2404:6800:4008:803::200e
  console.log(family);// 6
});

dns.reverse('203.188.200.67', (err, domain) => {
  // 反向解析IP地址
  console.log(domain);
  // [ 'media-router-fp1.prod.media.vip.tp2.yahoo.com' ]
});

您可能感兴趣的文章:

  • 浅析Node.js:DNS模块的使用
  • Nodejs下DNS缓存问题浅析
  • node.js中的dns.getServers方法使用说明