dns(域名服务器)#

稳定性: 2 - 稳定

源代码: lib/dns.js

dns 模块用于启用名称解析。 例如,使用它来查找主机名的 IP 地址。

尽管以域名系统(DNS)命名,但它并不总是使用 DNS 协议进行查找。 dns.lookup() 使用操作系统功能来执行名称解析。 它可能不需要执行任何网络通信。 若要像同一系统上其他应用程序一样执行名称解析,则使用 dns.lookup()

const dns = require('dns');

dns.lookup('example.org', (err, address, family) => {
console.log('地址: %j 地址族: IPv%s', address, family);
});
// 地址: "93.184.216.34" 地址族: IPv4

dns 模块中的所有其他函数都连接到实际的 DNS 服务器以执行名称解析。 它们将会始终使用网络执行 DNS 查询。 这些函数不使用与 dns.lookup() 使用的同一组配置文件(例如 /etc/hosts)。 使用这些函数可以始终执行 DNS 查询(绕过其他的名称解析功能)。

const dns = require('dns');

dns.resolve4('archive.org', (err, addresses) => {
  if (err) throw err;

  console.log(`地址: ${JSON.stringify(addresses)}`);

  addresses.forEach((a) => {
    dns.reverse(a, (err, hostnames) => {
      if (err) {
        throw err;
      }
      console.log(`地址 ${a} 逆向到: ${JSON.stringify(hostnames)}`);
    });
  });
});

有关更多信息,参见实现的注意事项

dns.Resolver 类#

DNS 请求的独立解析程序。

使用默认的设置创建一个新的解析程序。 使用 resolver.setServers() 为解析程序设置使用的服务器,则不会影响其他的解析程序:

const { Resolver } = require('dns');
const resolver = new Resolver();
resolver.setServers(['4.4.4.4']);

// 此请求将使用 4.4.4.4 中的服务器,与全局设置无关。
resolver.resolve4('example.org', (err, addresses) => {
  // ...
});

可以使用的 dns 模块的方法如下:

Resolver([options])#

Create a new resolver.

  • options <Object>
    • timeout <integer> Query timeout in milliseconds, or -1 to use the default timeout.

resolver.cancel()#

取消此解析程序所做的所有未完成的DNS查询。 使用错误码 ECANCELLED 调用相应的回调。

dns.getServers()#

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

[
  '4.4.4.4',
  '2001:4860:4860::8888',
  '4.4.4.4:1053',
  '[2001:4860:4860::8888]:1053'
]

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

  • hostname <string>
  • options <integer> | <Object>
    • family <integer> 记录的地址族。必须为 4600 值表示返回 IPv4 和 IPv6 地址。默认值: 0
    • hints <number> 一个或多个受支持的 getaddrinfo 标志。可以通过按位 OR 运算它们的值来传递多个标志。
    • all <boolean> 当为 true 时,则回调将会返回数组中所有已解析的地址。否则,返回单个地址。默认值: false
    • verbatim <boolean> 当为 true 时,则回调按 DNS 解析器返回的顺序接收 IPv4 和 IPv6 地址。当为 false 时,则 IPv4 地址放在 IPv6 地址之前。 默认值: 当前为 false(地址已重新排序)但预计在不久的将来会发生变化。新代码应使用 { verbatim: true }
  • callback <Function>
    • err <Error>
    • address <string> IPv4 或 IPv6 地址的字符串表示形式。
    • family <integer> 46,表示 address 的地址族,如果地址不是 IPv4 或 IPv6 地址,则为 00 可能是操作系统使用的名称解析服务中的错误的指示符。

解析主机名(例如:'apiref.com')为第一个找到的 A(IPv4)或 AAAA(IPv6)记录。 所有的 option 属性都是可选的。 如果 options 是整数,则只能是 46。 如果 options 没有被提供,则 IPv4 和 IPv6 都是有效的。

all 选项被设置为 true 时, callback 的参数会变为 (err, addresses),其中 addresses 变成一个由 addressfamily 属性组成的对象数组。

当发生错误时, err 是一个 Error 对象,其中 err.code 是错误码。 不仅在主机名不存在时,在如没有可用的文件描述符等情况下查找失败, err.code 也会被设置为 'ENOTFOUND'

dns.lookup() 不需要与 DNS 协议有任何关系。 它仅仅是一个连接名字和地址的操作系统功能。 在任何的 Node.js 程序中,它的实现对表现有一些微妙但是重要的影响。 在使用 dns.lookup() 之前请花些时间查询实现的注意事项章节。

使用示例:

const dns = require('dns');
const options = {
  family: 6,
  hints: dns.ADDRCONFIG | dns.V4MAPPED,
};
dns.lookup('example.com', options, (err, address, family) =>
  console.log('地址: %j 地址族: IPv%s', address, family));
// 地址: "2606:2800:220:1:248:1893:25c8:1946" 地址族: IPv6

// 当 options.all 为 true 时,则结果将会是一个数组。
options.all = true;
dns.lookup('example.com', options, (err, addresses) =>
  console.log('地址: %j', addresses));
// 地址: [{"address":"2606:2800:220:1:248:1893:25c8:1946","family":6}]

如果调用此方法的 util.promisify() 化的版本,并且 all 未设置为 true,则它返回的 Promise 会返回一个具有 addressfamily 属性的对象。

支持的 getaddrinfo#

以下内容可以作为 hints 标志传给 dns.lookup()

  • dns.ADDRCONFIG: Limits returned address types to the types of non-loopback addresses configured on the system. 例如,如果当前系统至少配置了一个 IPv4 地址,则返回 IPv4 地址。
  • dns.V4MAPPED: 如果指定了 IPv6 地址族,但是没有找到 IPv6 地址,则返回 IPv4 映射的 IPv6 地址。在有些操作系统中不支持(例如 FreeBSD 10.1)。
  • dns.ALL: 如果指定了 dns.V4MAPPED,则返回解析的 IPv6 地址以及 IPv4 映射的 IPv6 地址。

dns.lookupService(address, port, callback)#

使用操作系统的底层 getnameinfo 实现将给定的 addressport 解析为主机名和服务。

如果 address 不是有效的 IP 地址,则将会抛出 TypeErrorport 会被强制转换为数字。 如果它不是合法的端口,则抛出 TypeError

出错情况下, err 是一个 Error 对象,其中 err.code 是错误码。

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

如果调用此方法的 util.promisify() 化的版本,则它返回的 Promise 会返回一个具有 hostnameservice 属性的 Object

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

使用 DNS 协议将主机名(例如 'apiref.com')解析为一个资源记录的数组。 callback 函数的参数为 (err, records)。 当成功时, records 将会是一个资源记录的数组。 它的类型和结构取决于 rrtype

rrtyperecords 包含结果的类型快捷方法
'A'IPv4 地址 (默认)<string>dns.resolve4()
'AAAA'IPv6 地址<string>dns.resolve6()
'ANY'任何记录<Object>dns.resolveAny()
'CNAME'规范名称记录<string>dns.resolveCname()
'MX'邮件交换记录<Object>dns.resolveMx()
'NAPTR'名称权限指针记录<Object>dns.resolveNaptr()
'NS'名称服务器记录<string>dns.resolveNs()
'PTR'指针记录<string>dns.resolvePtr()
'SOA'开始授权记录<Object>dns.resolveSoa()
'SRV'服务记录<Object>dns.resolveSrv()
'TXT'文本记录<string[]>dns.resolveTxt()

当出错时, err 是一个 Error 对象,其中 err.codeDNS 错误码的一种。

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

  • hostname <string> 需要解析的主机名。
  • options <Object>
    • ttl <boolean> 记录每一条记录的存活次数 (TTL)。当为 true 时,回调会接收一个带有 TTL 秒数记录的类似 { address: '1.2.3.4', ttl: 60 } 对象的数组,而不是字符串的数组。
  • callback <Function>

使用 DNS 协议为 hostname 解析 IPv4 地址(A 记录)。 adresses 参数是传给 callback 函数的 IPv4 地址数组(例如:['74.125.79.104', '74.125.79.105', '74.125.79.106'])。

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

  • hostname <string> 需要解析的主机名。
  • options <Object>
    • ttl <boolean> 记录每一条记录的存活次数 (TTL)。当为 true 时,回调会接收一个带有 TTL 秒数记录的类似 { address: '0:1:2:3:4:5:6:7', ttl: 60 } 对象的数组,而不是字符串的数组。
  • callback <Function>

使用 DNS 协议为 hostname 解析 IPv6 地址(AAAA 记录)。 adresses 参数是传给 callback 函数的 IPv6 地址数组。

dns.resolveAny(hostname, callback)#

使用 DNS 协议解析所有记录(也称为 ANY* 查询)。 传给 callback 函数的 ret 参数将会是一个包含各种类型记录的数组。 每个对象都有一个 callback 属性,表明当前记录的类型。 根据 type,对象上将会显示其他属性:

类型属性
'A'address/ttl
'AAAA'address/ttl
'CNAME'value
'MX'指向 dns.resolveMx()
'NAPTR'指向 dns.resolveNaptr()
'NS'value
'PTR'value
'SOA'指向 dns.resolveSoa()
'SRV'指向 dns.resolveSrv()
'TXT'这种类型的记录包含一个名为 entries 的数组属性,它指向 dns.resolveTxt(),例如:{ entries: ['...'], type: 'TXT' }

以下是传给回调的 ret 对象的示例:

[ { 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 服务器运营商可以选择不响应 ANY 查询。 调用 dns.resolve4()dns.resolveMx() 等单个方法可能更好。 有关更多详细信息,请参见 RFC 8482

dns.resolveCname(hostname, callback)#

使用 DNS 协议为 hostname 解析 CNAME 记录。 传给 callback 函数的 adresses 参数将会包含可用于 hostname 的规范名称记录的数组(例如:['bar.example.com'])。

dns.resolveMx(hostname, callback)#

使用 DNS 协议为 hostname 解析邮件交换记录(MX 记录)。 传给 callback 函数的 adresses 参数将会包含具有 priorityexchange 属性的对象的数组(例如:[{priority: 10, exchange: 'mx.example.com'}, ...])。

dns.resolveNaptr(hostname, callback)#

使用 DNS 协议为 hostname 解析基于正则表达式的记录(NAPTR 记录)。 传给 callback 函数的 adresses 参数将会包含具有以下属性的对象数组:

  • flags
  • service
  • regexp
  • replacement
  • order
  • preference
{
  flags: 's',
  service: 'SIP+D2U',
  regexp: '',
  replacement: '_sip._udp.example.com',
  order: 30,
  preference: 100
}

dns.resolveNs(hostname, callback)#

使用 DNS 协议为 hostname 解析名称服务器记录(NS 记录)。 传给 callback 函数的 adresses 参数将会包含用于 hostname 的有效的名称服务器记录的数组(例如 ['ns1.example.com', 'ns2.example.com'])。

dns.resolvePtr(hostname, callback)#

使用 DNS 协议为 hostname 解析指针记录(PTR 记录)。 传给 callback 函数的 addresses 参数将会是一个包含回复记录的字符串数组。

dns.resolveSoa(hostname, callback)#

使用 DNS 协议为 hostname 解析开始权限记录(SOA 记录)。 传给 callback 函数的 addresses 参数将会是一个具有以下属性的对象:

  • nsname
  • hostmaster
  • serial
  • refresh
  • retry
  • expire
  • minttl
{
  nsname: 'ns.example.com',
  hostmaster: 'root.example.com',
  serial: 2013101809,
  refresh: 10000,
  retry: 2400,
  expire: 604800,
  minttl: 3600
}

dns.resolveSrv(hostname, callback)#

使用 DNS 协议为 hostname 解析服务记录(SRV 记录)。 传给 callback 函数的 addresses 参数将会是一个具有以下属性的对象数组:

  • priority
  • weight
  • port
  • name
{
  priority: 10,
  weight: 5,
  port: 21223,
  name: 'service.example.com'
}

dns.resolveTxt(hostname, callback)#

使用 DNS 协议为 hostname 解析文本查询(TXT 记录)。 传给 callback 函数的 records 参数是一个具有用于 hostname 的可用的文本记录的二维数组(例如:[ ['v=spf1 ip4:0.0.0.0 ', '~all' ] ])。 每个子数组包含一条 TXT 记录块。 根据用例,这些可以是连接在一起或单独对待。

dns.reverse(ip, callback)#

执行一个反向 DNS 查询,将 IPv4 或 IPv6 地址解析为主机名数组。

当出错时, err 是一个 Error 对象,其中 err.codeDNS 错误码之一。

dns.setServers(servers)#

设置执行 DNS 解析时要使用的服务器的 IP 地址和端口。 servers 参数是 RFC 5952 格式的地址数组。 如果端口是 IANA 默认的 DNS 端口(53),则可以省略。

dns.setServers([
  '4.4.4.4',
  '[2001:4860:4860::8888]',
  '4.4.4.4:1053',
  '[2001:4860:4860::8888]:1053'
]);

如果提供了无效地址,则会抛出错误。

DNS 查询正在进行时,不得调用 dns.setServers() 方法。

dns.setServers() 方法仅影响 dns.resolve()dns.resolve*()dns.reverse()(特别是 dns.lookup())。

这个方法很像 resolve.conf。 也就是说,如果尝试使用提供的第一个服务器解析会导致 NOTFOUND 错误,则 resolve() 方法将不会尝试使用提供的后续服务器进行解析。 仅当较早的 DNS 服务器超时或导致其他一些错误时,才会使用后备 DNS 服务器。

Promise 形式的 API#

在使用dns.promises时,它也提供了API的另一种调用形式,即使用Promise来代替callbacks。这个DNS的Promise对象来自require('dns').promises

dnsPromises.Resolver 类#

一个DNS请求的独立解析器。

创建新的解析器将使用默认服务器设置。使用resolver.setServers()设置解析器的服务器并不会影响其他的解析器:

const { Resolver } = require('dns').promises;
const resolver = new Resolver();
resolver.setServers(['4.4.4.4']);

// 该请求使用4.4.4.4的服务器,独立于全局设置。
resolver.resolve4('example.org').then((addresses) => {
  // ...
});

// 或者, 你可以用`async-await`编写异步代码。
(async function() {
  const addresses = await resolver.resolve4('example.org');
})();

以下是dns.Promises API提供的方法。

dnsPromises.getServers()#

返回一个格式为[RFC 5952][]的IP地址字符串数组, 这个IP地址字符串数组配置于DNS解析文件。如果使用了自定义的端口,那么字符串将包含端口值。

[
  '4.4.4.4',
  '2001:4860:4860::8888',
  '4.4.4.4:1053',
  '[2001:4860:4860::8888]:1053'
]

dnsPromises.lookup(hostname[, options])#

  • hostname <string>

  • options <integer> | <Object>

    • family <integer> 地址类型必须是4, 6, or 0。其中, 0代表同时返回了IPv4和IPv6地址。默认值是0
    • hints <number> 传递一个或者多个支持的 getaddrinfo类型标志。多个类型记录可以或运算符连接起来。
    • all <boolean> 当值为true的时候, Promise会承诺解决数组里面的全部IP地址。 否则的话,仅仅解决单一地址。默认值是false
    • verbatim <boolean> 当值为true的时候, Promise的API使用DNS解析器根据他们返回的顺序使用IPv4和IPv6地址进行解析。 如果为false,则将IPv4地址放在IPv6地址之前进行解析。 默认值:false(地址已重新排序), 但预计在不久的将来会改变。新代码应使用{ verbatim: true }

    把一个主机名(例如'nodejs.org')解析为第一个找到的A(IPv4)或AAAA(IPv6)IP地址。 所有option属性都是可选的。如果options为整型,则值必须为46

    • 如果options未提供,则返回能够找到的IPv4和IPv6地址。

all选项设置为true时,将使用地址为具有属性addressfamily属性的对象数组来解析Promise

发生错误时, Promise会被Error对象拒绝,其中“ err.code”是错误代码, 请注意一点, err.code的值,不仅仅在主机名不存在时,同时在查找以其他方式 (例如,没有可用的文件描述符)失败时, err.code都将被设置为 'ENOTFOUND'

dnsPromises.lookup() 不一定与DNS协议有关。该实现使用操作系统工具,该工具可以将名称与地址相关联,反之亦然。 这种操作实现会对任何Node.js程序的行为产生微妙重要的后果。 因此,在使用dnsPromises.lookup()之前,请花一些时间查看注意事项Implementation considerations section

Example usage:

const dns = require('dns');
const dnsPromises = dns.promises;
const options = {
  family: 6,
  hints: dns.ADDRCONFIG | dns.V4MAPPED,
};

dnsPromises.lookup('example.com', options).then((result) => {
  console.log('address: %j family: IPv%s', result.address, result.family);
  // address: "2606:2800:220:1:248:1893:25c8:1946" family: IPv6
});

// 当options.all为true时,结果将为数组。
options.all = true;
dnsPromises.lookup('example.com', options).then((result) => {
  console.log('addresses: %j', result);
  // addresses: [{"address":"2606:2800:220:1:248:1893:25c8:1946","family":6}]
});

dnsPromises.lookupService(address, port)#

使用操作系统底层的getnameinfo实现去解析address and port得到主机名和服务。

如果address不是有效的IP地址,则将引发TypeError。 该端口必须为一个数字。 如果不是合法端口,则将引发TypeError

发生错误时, Promise将被Error对象拒绝,其中err.code是错误代码。

const dnsPromises = require('dns').promises;
dnsPromises.lookupService('127.0.0.1', 22).then((result) => {
  console.log(result.hostname, result.service);
  // Prints: localhost ssh
});

dnsPromises.resolve(hostname[, rrtype])#

  • hostname <string> Host name to resolve.
  • rrtype <string> Resource record type. Default: 'A'.

使用DNS协议将主机名(例如“ nodejs.org”)解析为资源记录的数组。 成功后,将通过一系列资源记录来解决实现Promise。 各个结果的类型和结构根据rrtype的不同而有所不同:

rrtyperecords containsResult typeShorthand method
'A'IPv4 地址(默认)<string>dnsPromises.resolve4()
'AAAA'IPv6 地址<string>dnsPromises.resolve6()
'ANY'任何记录<Object>dnsPromises.resolveAny()
'CNAME'规范名称记录<string>dnsPromises.resolveCname()
'MX'将域名指向邮件服务器地址<Object>dnsPromises.resolveMx()
'NAPTR'名称权限指针记录<Object>dnsPromises.resolveNaptr()
'NS'将子域名指定其他DNS服务器解析<string>dnsPromises.resolveNs()
'PTR'指针记录<string>dnsPromises.resolvePtr()
'SOA'权限记录的开始<Object>dnsPromises.resolveSoa()
'SRV'记录提供特定的服务的服务器<Object>dnsPromises.resolveSrv()
'TXT'文本长度限制512,通常做SPF记录(反垃圾邮件)<string[]>dnsPromises.resolveTxt()

如果出错,则Promise会被Error对象拒绝,其中err.codeDNS错误代码之一。

dnsPromises.resolve4(hostname[, options])#

  • hostname <string> 要解析的主机名。

  • options <Object>

    • ttl <boolean> 检索每个记录的生存时间值(TTL)。 如果为true,则使用数组{ address: '1.2.3.4', ttl: 60 }对象而不是字符串数组来解析Promise,而TTL以秒表示。

    Retrieve the Time-To-Live value (TTL) of each record. When true, the Promise is resolved with an array of { address: '1.2.3.4', ttl: 60 } objects rather than an array of strings, with the TTL expressed in seconds.

使用DNS协议为以下地址解析IPv4地址(A 记录)主机名。 成功后,将通过一系列IPv4解决Promise地址(比如, ['74.125.79.104', '74.125.79.105', '74.125.79.106']

dnsPromises.resolve6(hostname[, options])#

  • hostname <string> 要解析的主机名。.
  • options <Object>
    • ttl <boolean> 检索每个记录的生存时间值(TTL)。 如果为true,则使用数组对象{ address: '0:1:2:3:4:5:6:7', ttl: 60 }而不是字符串数组来解析Promise。 TTL以秒表示。

使用DNS协议解析hostname的IPv6地址(AAAA记录)。 成功后,将使用一系列IPv6地址解析Promise

dnsPromises.resolveAny(hostname)#

Uses the DNS protocol to resolve all records (also known as ANY or * query). On success, the Promise is resolved with an array containing various types of records. Each object has a property type that indicates the type of the current record. And depending on the type, additional properties will be present on the object:

TypeProperties
'A'address/ttl
'AAAA'address/ttl
'CNAME'value
'MX'Refer to dnsPromises.resolveMx()
'NAPTR'Refer to dnsPromises.resolveNaptr()
'NS'value
'PTR'value
'SOA'Refer to dnsPromises.resolveSoa()
'SRV'Refer to dnsPromises.resolveSrv()
'TXT'This type of record contains an array property called entries which refers to dnsPromises.resolveTxt(), e.g. { entries: ['...'], type: 'TXT' }

Here is an example of the result object:

[ { 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 } ]

dnsPromises.resolveCname(hostname)#

使用DNS协议解析hostnameCNAME记录。 成功完成后,将使用一系列可用于主机名的规范名称记录来解决Promise(例如 `['bar.example.com'])。

dnsPromises.resolveMx(hostname)#

使用DNS协议解析hostname的邮件交换记录(MX记录)。 成功后, Promise将通过一系列包含优先级交换属性的对象来解决(例如, [{priority: 10, exchange: 'mx.example.com'}, ...] )。

dnsPromises.resolveNaptr(hostname)#

使用DNS协议解析主机名的基于正则表达式的记录(NAPTR记录)。 成功后,将使用具有以下属性的对象数组来解决 Promise

  • flags
  • service
  • regexp
  • replacement
  • order
  • preference
{
  flags: 's',
  service: 'SIP+D2U',
  regexp: '',
  replacement: '_sip._udp.example.com',
  order: 30,
  preference: 100
}

dnsPromises.resolveNs(hostname)#

Uses the DNS protocol to resolve name server records (NS records) for the hostname. On success, the Promise is resolved with an array of name server records available for hostname (e.g. ['ns1.example.com', 'ns2.example.com']).

dnsPromises.resolvePtr(hostname)#

Uses the DNS protocol to resolve pointer records (PTR records) for the hostname. On success, the Promise is resolved with an array of strings containing the reply records.

dnsPromises.resolveSoa(hostname)#

Uses the DNS protocol to resolve a start of authority record (SOA record) for the hostname. On success, the Promise is resolved with an object with the following properties:

  • nsname
  • hostmaster
  • serial
  • refresh
  • retry
  • expire
  • minttl
{
  nsname: 'ns.example.com',
  hostmaster: 'root.example.com',
  serial: 2013101809,
  refresh: 10000,
  retry: 2400,
  expire: 604800,
  minttl: 3600
}

dnsPromises.resolveSrv(hostname)#

Uses the DNS protocol to resolve service records (SRV records) for the hostname. On success, the Promise is resolved with an array of objects with the following properties:

  • priority
  • weight
  • port
  • name
{
  priority: 10,
  weight: 5,
  port: 21223,
  name: 'service.example.com'
}

dnsPromises.resolveTxt(hostname)#

Uses the DNS protocol to resolve text queries (TXT records) for the hostname. On success, the Promise is resolved with a two-dimensional array of the text records available for hostname (e.g. [ ['v=spf1 ip4:0.0.0.0 ', '~all' ] ]). Each sub-array contains TXT chunks of one record. Depending on the use case, these could be either joined together or treated separately.

dnsPromises.reverse(ip)#

Performs a reverse DNS query that resolves an IPv4 or IPv6 address to an array of host names.

On error, the Promise is rejected with an Error object, where err.code is one of the DNS error codes.

dnsPromises.setServers(servers)#

Sets the IP address and port of servers to be used when performing DNS resolution. The servers argument is an array of RFC 5952 formatted addresses. If the port is the IANA default DNS port (53) it can be omitted.

dnsPromises.setServers([
  '4.4.4.4',
  '[2001:4860:4860::8888]',
  '4.4.4.4:1053',
  '[2001:4860:4860::8888]:1053'
]);

An error will be thrown if an invalid address is provided.

The dnsPromises.setServers() method must not be called while a DNS query is in progress.

This method works much like resolve.conf. That is, if attempting to resolve with the first server provided results in a NOTFOUND error, the resolve() method will not attempt to resolve with subsequent servers provided. Fallback DNS servers will only be used if the earlier ones time out or result in some other error.

错误码#

每次 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.LOADIPHLPAPI: 加载 iphlpapi.dll 错误。
  • dns.ADDRGETNETWORKPARAMS: 找不到 GetNetworkParams 函数。
  • dns.CANCELLED: DNS 查询取消。

实现的注意事项#

尽管 dns.lookup() 和各种变形的 dns.resolve*()/dns.reverse() 函数有相同的目标,将网络的名字与网络地址联系在一起(反之亦然),但它们的行为是完全不同的。 这些差异虽然微妙但对 Node.js 程序的行为有重大的影响。

dns.lookup()#

在底层,dns.lookup() 使用的操作系统设施与大多数其他程序相同。 例如,dns.lookup() 几乎总是解析给定的主机名,与 ping 命令一样。 在大多数类 POSIX 操作系统中,dns.lookup() 函数的行为可以通过改变 nsswitch.conf(5) 和/或 resolv.conf(5) 的设置进行改变,但是需要注意改变这些文件就意味着改变所有正在这个操作系统中运行的所有程序的行为。

尽管以异步 JavaScript 的角度来调用 dns.lookup(),但在内部 libuv 底层线程池中却是同步的调用 getaddrinfo(3)。 这可能会对某些应用程序产生令人惊讶的负面性能影响,有关详细信息,请参见 UV_THREADPOOL_SIZE 文档。

各种网络 API 将会在内部调用 dns.lookup() 来解析主机名。 如果这是一个问题,请考虑使用 dns.resolve() 并使用地址而不是主机名来将主机名解析为地址。 此外,某些网络 API(例如 socket.connect()dgram.createSocket() 允许替换默认解析器 dns.lookup()

dns.resolve()、dns.resolve*() 与 dns.reverse()#

这些函数实现与 dns.lookup() 截然不同。 它们没有使用 getaddrinfo(3) 并且通过网络执行 DNS 查询。 网络通信始终是异步处理的,并且没有使用 libuv 线程池。

因此,这些函数不会像使用 libuv 线程池的 dns.lookup() 函数一样会对其它进程有负面影响。

它们不像 dns.lookup() 一样使用相同的配置文件。 例如,它们不会使用来自 /etc/hosts 的配置。