DNS(Domain Name System,域名系统),DNS协议运行在UDP协议之上,使用端口号53。DNS是因特网上作为域名和IP地址相互映射的一个分布式数据库,能够使用户更方便的访问互联网,而不用去记住能够被机器直接读取的IP数串。简单的说,就是把域名(网址)解析成对应的IP地址。Node.js的dns
模块,提供了DNS解析功能。当使用dns
模块中的net.connect(80, 'itbilu.com')
方法 或 http
模块的http.get({ host: 'itbilu.com' })
方法时,在其底层会使用dns
模块中的dns.lookup
方法进行域名解析。
1. dns
模块的两种域名解析方式
在dns
模块中,对域名的解析有两种方式:1. 使用操作系统底层的DNS服务解析、2. 连接到DNS服务器解析域名
使用操作系统底层的DNS服务解析:进行域名解析时,不需要连接到网络仅使用系统自带DNS解析功能。这个功能由 dns.lookup()
方法实现。
使用dns.lookup()
方法解析itbilu.com
:
var dns = require('dns'); dns.lookup('itbilu.com', function (err, addresses, family) { console.log('IP地址:%s,协议版本:%s', addresses, family); }); //IP地址:115.28.135.70,协议版本:4
连接到DNS服务器解析域名:在dns
模块中,除 dns.lookup()
方法外都是使用DNS服务器进行域名解析,解析时需要连接到网络。
使用dns.resolve4()
方法解析itbilu.com
:
dns.resolve4('www.itbilu.com', function (err, addresses) { if (err) throw err; console.log('IP地址:: ' + JSON.stringify(addresses)); }); //IP地址:: ["115.28.135.70"]
2. dns
模块中的域名解析方法
2.1 dns.lookup(hostname[, options], callback)
:将一个域名(如:'itbilu.com.com')解析为第一个找到的 A 记录(IPv4)或 AAAA 记录(IPv6)
hostname
表示要解析的域名。
options
可以是一个对象或整数。如果没有提供options
参数,则IP v4 和 v6 地址都可以。如果 options
是整数,则必须是 4
或6
。如果 options
是对象时,会包含以下两个可选参数:
-
family
:可选,IP版本。如果提供,必须是4
或6
。不提供则,IP v4 和 v6 地址都可以 -
hints
:可选。如果提供,可以是一个或者多个getaddrinfo
标志。若不提供,则没有标志会传给getaddrinfo
。
callback
回调函数,参数包含(err, address, family)
。出错时,参数 err
是 Error
对象。address
参数表示 IP v4 或 v6 地址。family
参数是4 或 6,表示 address
协议版本。
2.2 dns.resolve(hostname[, rrtype], callback)
:将一个域名(如 'itbilu.com.com')解析为一个rrtype
指定类型的数组
hostname
表示要解析的域名。
rrtype
有以下可用值:
-
'A'
:IPv4 地址,缺省 -
'AAAA'
:IPv4 地址 -
'MX'
:邮件交换记录 -
'TXT'
:text 文本记录 -
'SRV'
:SRV 记录 -
'PTR'
:反向 IP 查找 -
'NS'
:域名服务器记录 -
'CNAME'
:别名记录 -
'SOA'
:授权记录的初始值
callback
回调函数,参数包含(err, addresses)
。出错时,参数 err
是 Error
对象。addresses
根据记录类型的不同返回值也不同。
除使用dns.resolve()
进行DNS解析外,dns
模块还提供了几个快捷方法,它们只按某一种有效rrtype
类型进行解析。
2.3 dns.resolve4(hostname, callback)
:查询域名的IPv4
记录,即:A
记录
hostname
表示要解析的域名。
callback
回调函数,参数包含(err, addresses)
。出错时,参数 err
是 Error
对象。addresses
为IPv4地址数组,如:['74.125.79.104', '74.125.79.105', '74.125.79.106']
。
2.4 dns.resolve6(hostname, callback)
:查询域名的IPv6
记录,即:AAAA
记录
hostname
表示要解析的域名。
callback
回调函数,参数包含(err, addresses)
。出错时,参数 err
是 Error
对象。addresses
为IPv6地址数组,如:['2404:6800:4005:80b::2004']
。
2.5 dns.resolveMx(hostname, callback)
:查询邮件交换记录,即:MX
记录
hostname
表示要解析的域名。
callback
回调函数,参数包含(err, addresses)
。出错时,参数 err
是 Error
对象。addresses
是MX记录数组, 每一项包含优先级和交换属性,如:[{'priority': 10, 'exchange': 'mx.example.com'},...]
。
2.6 dns.resolveTxt(hostname, callback)
:查询文本记录,即:TXT
记录
hostname
表示要解析的域名。
callback
回调函数,参数包含(err, addresses)
。出错时,参数 err
是 Error
对象。addresses
为domain
可用文本记录的数组,如:['v=spf1 ip4:0.0.0.0 ~all']
。
2.7 dns.resolveSrv(domain, callback)
:仅能进行服务记录查询,即:SRV
记录
hostname
表示要解析的域名。
callback
回调函数,参数包含(err, addresses)
。出错时,参数 err
是 Error
对象。addresses
是hostname
可用的 SRV 记录数组。 SRV记录属性有:优先级(priority)、权重(weight)、端口(port)、名称(name)。如:[{'priority': 10, 'weight': 5, 'port': 21223, 'name': 'service.example.com'}, ...]
。
2.8 dns.resolveSoa(hostname, callback)
:查询授权记录,即:SOA
记录
hostname
表示要解析的域名。
callback
回调函数,参数包含(err, addresses)
。出错时,参数 err
是 Error
对象。addresses
是一个包含以下属性的对象:
{ nsname: 'ns.example.com', hostmaster: 'root.example.com', serial: 2013101809, refresh: 10000, retry: 2400, expire: 604800, minttl: 3600 }
2.9 dns.resolveNs(hostname, callback)
:查询域名服务器查询,即:NS
记录
hostname
表示要解析的域名。
callback
回调函数,参数包含(err, addresses)
。出错时,参数 err
是 Error
对象。addresses
是域名服务器记录数组。如:['ns1.example.com', 'ns2.example.com']
。
2.10 dns.resolveCname(hostname, callback)
:查询别名记录,即:CNAME
记录
hostname
表示要解析的域名。
callback
回调函数,参数包含(err, addresses)
。出错时,参数 err
是 Error
对象。addresses
是域名可用的别名记录数组 。如:['bar.example.com']
。
3. dns
模块中的IP反查方法
3.1 dns.lookupService(address, port, callback)
:使用getnameinfo
方法将传入的地址和端口解析为域名和服务
address
表示要解析的IP地址字符串。
port
表示要解析的端口号。
callback
回调函数,参数包含(err, hostname, service)
。出错时,参数 err
是 Error
对象。hostname
和 service
都是字符串 (比如 'localhost'
和 'http'
)。
var dns = require('dns'); dns.lookupService('127.0.0.1', 80, function(err, hostname, service){ if (err) throw err; console.log('主机名:%s,服务类型:%s', hostname, service); }) //主机名:localhost,服务类型:http
3.2 dns.reverse(ip, callback)
:反向解析IP地址,返回指向该 IP 地址的域名数组
ip
表示要反向解析的IP地址。
callback
回调函数,参数包含(err, domains)
。出错时,参数 err
是 Error
对象。domains
解析后的域名数组。
4. 模块中的其它方法和错误码
4.1 DNS服务器设置与获取
dns.getServers()
:获取用于解析的 IP 地址的字符串数组,即:获取DNS服务器地址
dns.setServers(servers)
:设置用于解析的 IP 地址的字符串数组,即:设置DNS服务器地址
var dns = require('dns'); var ips = dns.getServers(); console.log('当前DNS服务器:', JSON.stringify(ips)); //当前DNS服务器: ["192.168.1.1"] //重新设置DNS服务器IP dns.setServers(['8.8.4.4']); var newIps = dns.getServers(); console.log('设置后DNS服务器:', JSON.stringify(newIps)); //设置后DNS服务器: ["8.8.4.4"]
4.3 dns
模块可能出现的错误
在dns
模块进行域名解析或DNS查询时,可能会出现以下错误:
-
dns.NODATA
:DNS服务器返回无数据应答。 -
dns.FORMERR
:DNS服务器查返回询格式错误。 -
dns.SERVFAIL
:DNS服务器返回一般失败。 -
dns.NOTFOUND
:域名未找到。 -
dns.NOTIMP
: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
:非法HINTS标识符。 -
dns.NOTINITIALIZED
:c-ares 库尚未初始化。 -
dns.LOADIPHLPAPI
:加载 iphlpapi.dll 出错。 -
dns.ADDRGETNETWORKPARAMS
:无法找到 GetNetworkParams 函数。 -
dns.CANCELLED
:取消 DNS 查询。