DNS#

穩定性:2 - 穩定

原始碼: lib/dns.js

node:dns 模組可啟用名稱解析。例如,使用它來查詢主機名稱的 IP 位址。

雖然以 網域名稱系統 (DNS) 命名,但它並不總是使用 DNS 協定進行查詢。 dns.lookup() 使用作業系統功能來執行名稱解析。它可能不需要執行任何網路通訊。若要以與系統上其他應用程式相同的方式執行名稱解析,請使用 dns.lookup()

const dns = require('node:dns');

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

node:dns 模組中的所有其他函式都會連線到實際的 DNS 伺服器來執行名稱解析。它們將始終使用網路來執行 DNS 查詢。這些函式不會使用 dns.lookup() 使用的相同組態檔集(例如 /etc/hosts)。使用這些函式始終執行 DNS 查詢,繞過其他名稱解析功能。

const dns = require('node:dns');

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

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

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

請參閱 實作考量區段 以取得更多資訊。

類別:dns.Resolver#

DNS 要求的獨立解析器。

建立新的解析器會使用預設伺服器設定。使用 resolver.setServers() 設定解析器使用的伺服器不會影響其他解析器

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

// This request will use the server at 4.4.4.4, independent of global settings.
resolver.resolve4('example.org', (err, addresses) => {
  // ...
}); 

node:dns 模組中的下列方法可用

Resolver([options])#

建立新的解析器。

  • options <Object>
    • timeout <integer> 查詢逾時(毫秒),或 -1 以使用預設逾時。
    • tries <integer> 解析器在放棄之前嘗試與每個名稱伺服器建立連線的次數。預設:4

resolver.cancel()#

取消此解析器所做的所有未完成 DNS 查詢。對應的回呼函式會以包含程式碼 ECANCELLED 的錯誤呼叫。

resolver.setLocalAddress([ipv4][, ipv6])#

  • ipv4 <string> IPv4 位址的字串表示形式。預設:'0.0.0.0'
  • ipv6 <string> IPv6 位址的字串表示形式。預設:'::0'

解析器執行個體會從指定的 IP 位址傳送其要求。這允許程式在多宿主系統上使用時指定傳送介面。

如果未指定 v4 或 v6 位址,則會設定為預設值,而作業系統會自動選擇本機位址。

解析器在向 IPv4 DNS 伺服器發出請求時將使用 v4 本機地址,在向 IPv6 DNS 伺服器發出請求時將使用 v6 本機地址。解析請求的 rrtype 對所使用的本機地址沒有影響。

dns.getServers()#

傳回目前設定用於 DNS 解析的 IP 位址字串陣列,格式符合 RFC 5952。如果使用自訂埠,字串將包含埠區段。

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

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

  • hostname <string>
  • options <integer> | <Object>
    • family <整數> | <字串> 記錄家族。必須為 460。為了向後相容,'IPv4''IPv6' 分別被解釋為 46。值 0 表示傳回 IPv4 或 IPv6 位址。如果值 0{ all: true } (請參閱下方) 一起使用,則會傳回 IPv4 和 IPv6 位址。預設值:0
    • hints <數字> 一個或多個 支援的 getaddrinfo 旗標。多個旗標可以透過按位元 OR 其值來傳遞。
    • all <布林值> 當為 true 時,呼叫回傳值會在陣列中傳回所有已解析的位址。否則,傳回單一位址。預設值:false
    • verbatim <布林值> 當為 true 時,呼叫回傳值會按照 DNS 解析器傳回的順序接收 IPv4 和 IPv6 位址。當為 false 時,IPv4 位址會置於 IPv6 位址之前。預設值:true (位址不會重新排序)。預設值可以使用 dns.setDefaultResultOrder()--dns-result-order 來設定。
  • callback <函式>
    • err <錯誤>
    • address <字串> IPv4 或 IPv6 位址的字串表示形式。
    • family <整數> 46,表示 address 的家族,如果位址不是 IPv4 或 IPv6 位址,則為 00 很可能是作業系統使用的名稱解析服務中的錯誤指標。

將主機名稱(例如 'nodejs.org')解析為找到的第一個 A(IPv4)或 AAAA(IPv6)記錄。所有 option 屬性都是可選的。如果 options 是整數,則它必須是 46 – 如果 options0 或未提供,則如果找到,則會同時傳回 IPv4 和 IPv6 位址。

all 選項設定為 truecallback 的參數會變更為 (err, addresses),其中 addresses 是包含 addressfamily 屬性的物件陣列。

發生錯誤時,errError 物件,其中 err.code 是錯誤代碼。請注意,err.code 不僅會在主機名稱不存在時設定為 'ENOTFOUND',還會在查詢以其他方式失敗時設定,例如沒有可用的檔案描述符。

dns.lookup() 不一定與 DNS 協定有關。實作使用作業系統功能,可以將名稱與位址關聯,反之亦然。此實作可能會對任何 Node.js 程式產生細微但重要的影響。請在使用 dns.lookup() 之前花點時間參閱 實作考量區段

範例用法

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

// When options.all is true, the result will be an Array.
options.all = true;
dns.lookup('example.com', options, (err, addresses) =>
  console.log('addresses: %j', addresses));
// addresses: [{"address":"2606:2800:220:1:248:1893:25c8:1946","family":6}] 

如果此方法以其 util.promisify() 版本呼叫,且 all 未設定為 true,則會傳回包含 addressfamily 屬性的 ObjectPromise

支援的 getaddrinfo 旗標#

下列旗標可以作為提示傳遞給 dns.lookup()

  • dns.ADDRCONFIG:將傳回的位址類型限制為系統上設定的非迴圈位址類型。例如,只有當目前系統至少設定一個 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('node:dns');
dns.lookupService('127.0.0.1', 22, (err, hostname, service) => {
  console.log(hostname, service);
  // Prints: localhost ssh
}); 

如果此方法作為其 util.promisify() 版本被呼叫,它會傳回一個包含 hostnameservice 屬性的 ObjectPromise

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

使用 DNS 協定將主機名稱(例如 'nodejs.org')解析為資源記錄陣列。callback 函數有參數 (err, records)。成功時,records 會是資源記錄陣列。個別結果的類型和結構會根據 rrtype 而有所不同

rrtyperecords 包含結果類型簡寫方法
'A'IPv4 位址(預設)<string>dns.resolve4()
'AAAA'IPv6 位址<string>dns.resolve6()
'ANY'任何記錄<Object>dns.resolveAny()
'CAA'CA 授權記錄<Object>dns.resolveCaa()
'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()

發生錯誤時,errError 物件,其中 err.code 是其中一個 DNS 錯誤碼

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

  • hostname <string> 要解析的主機名稱。
  • options <Object>
    • ttl <boolean> 擷取每筆記錄的生存時間 (TTL) 值。當 true 時,回呼函式會收到一個 { address: '1.2.3.4', ttl: 60 } 物件陣列,而不是字串陣列,TTL 以秒為單位表示。
  • callback <函式>

使用 DNS 協定來解析 hostname 的 IPv4 位址 (A 記錄)。傳遞給 callback 函式的 addresses 引數將包含一個 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 時,回呼函式會收到一個 { address: '0:1:2:3:4:5:6:7', ttl: 60 } 物件陣列,而不是字串陣列,TTL 以秒為單位表示。
  • callback <函式>

使用 DNS 協定解析 IPv6 位址(AAAA 記錄)的 hostname。傳遞給 callback 函式的 addresses 參數將包含 IPv6 位址陣列。

dns.resolveAny(hostname, callback)#

使用 DNS 協定解析所有記錄(也稱為 ANY* 查詢)。傳遞給 callback 函式的 ret 參數將是包含各種記錄類型的陣列。每個物件都有 type 屬性,用於指出目前記錄的類型。根據 type,物件上將會存在其他屬性

類型屬性
'A'address/ttl
'AAAA'address/ttl
'CNAME'
'MX'參閱 dns.resolveMx()
'NAPTR'參閱 dns.resolveNaptr()
'NS'
'PTR'
「SOA」參閱 dns.resolveSoa()
「SRV」參閱 dns.resolveSrv()
「TXT」這種類型的記錄包含稱為 entries 的陣列屬性,它指的是 dns.resolveTxt(),例如 { entries: ['...'], type: 'TXT' }

以下是傳遞給 callback 的 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 協定解析 hostnameCNAME 記錄。傳遞給 callback 函式的 addresses 引數會包含一個可供 hostname 使用的正規名稱記錄陣列(例如 ['bar.example.com'])。

dns.resolveCaa(hostname, callback)#

使用 DNS 協定解析 hostnameCAA 記錄。傳遞給 callback 函式的 addresses 引數會包含一個可供 hostname 使用的認證機構授權記錄陣列(例如 [{critical: 0, iodef: 'mailto:[email protected]'}, {critical: 128, issue: 'pki.example.com'}])。

dns.resolveMx(hostname, callback)#

使用 DNS 協定解析 hostname 的郵件交換記錄(MX 記錄)。傳遞給 callback 函式的 addresses 引數會包含一個物件陣列,其中同時包含 priorityexchange 屬性(例如 [{priority: 10, exchange: 'mx.example.com'}, ...])。

dns.resolveNaptr(hostname, callback)#

使用 DNS 協定來解析 hostname 的基於正規表示式的記錄 (NAPTR 記錄)。傳遞給 callback 函式的 addresses 參數將包含一個物件陣列,其中包含下列屬性

  • 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 函式的 addresses 參數將包含一個可供 hostname 使用的名稱伺服器記錄陣列 (例如 ['ns1.example.com', 'ns2.example.com'])。

dns.resolvePtr(hostname, callback)#

使用 DNS 協定來解析 hostname 的指標記錄 (PTR 記錄)。傳遞給 callback 函式的 addresses 參數將會是一個包含回覆記錄的字串陣列。

dns.resolveSoa(hostname, callback)#

使用 DNS 協定來解析 hostname 的權威開始記錄 (SOA 記錄)。傳遞給 callback 函式的 address 參數將會是一個包含下列屬性的物件

  • nsname
  • hostmaster
  • serial
  • refresh
  • 重試
  • 過期
  • 最小生存時間
{
  nsname: 'ns.example.com',
  hostmaster: 'root.example.com',
  serial: 2013101809,
  refresh: 10000,
  retry: 2400,
  expire: 604800,
  minttl: 3600
} 

dns.resolveSrv(hostname, callback)#

使用 DNS 協定來解析服務記錄 (SRV 記錄) 以取得 hostname。傳遞給 callback 函式的 addresses 參數會是一個物件陣列,具有下列屬性

  • 優先順序
  • 權重
  • 名稱
{
  priority: 10,
  weight: 5,
  port: 21223,
  name: 'service.example.com'
} 

dns.resolveTxt(hostname, callback)#

使用 DNS 協定來解析文字查詢 (TXT 記錄) 以取得 hostname。傳遞給 callback 函式的 records 參數是 hostname 可用的文字記錄的二維陣列 (例如 [ ['v=spf1 ip4:0.0.0.0 ', '~all' ] ])。每個子陣列包含一個記錄的 TXT 區塊。根據使用案例,這些區塊可以合併在一起或分開處理。

dns.reverse(ip, callback)#

執行反向 DNS 查詢,將 IPv4 或 IPv6 位址解析為一組主機名稱。

發生錯誤時,errError 物件,其中 err.code 是其中一個 DNS 錯誤碼

dns.setDefaultResultOrder(order)#

  • order <string> 必須是 'ipv4first''verbatim'

dns.lookup()dnsPromises.lookup() 中設定 verbatim 的預設值。值可以是

  • ipv4first:設定預設 verbatimfalse
  • verbatim:設定預設 verbatimtrue

預設為 verbatim,且 dns.setDefaultResultOrder() 的優先權高於 --dns-result-order。當使用 工作執行緒 時,主執行緒的 dns.setDefaultResultOrder() 函式不會影響工作執行緒中的預設 DNS 順序。

dns.getDefaultResultOrder()#

取得 dns.lookup()dnsPromises.lookup()verbatim 的預設值。值可以是

  • ipv4firstverbatim 預設為 false
  • verbatimverbatim 預設為 true

dns.setServers(servers)#

設定執行 DNS 解析時要使用的伺服器 IP 位址和埠號。servers 參數是 RFC 5952 格式位址的陣列。如果埠號是 IANA 預設 DNS 埠號 (53),則可以省略。

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

如果提供無效的位址,將擲回錯誤。

當 DNS 查詢正在進行時,不得呼叫 dns.setServers() 方法。

dns.setServers() 方法只會影響 dns.resolve()dns.resolve*()dns.reverse()(特別不會影響 dns.lookup())。

此方法的運作方式與 resolve.conf 非常類似。也就是說,如果嘗試使用提供的第 1 個伺服器解析,但結果為 NOTFOUND 錯誤,resolve() 方法不會嘗試使用後續提供的伺服器進行解析。只有在較早的伺服器逾時或導致其他錯誤時,才會使用備用 DNS 伺服器。

DNS Promises API#

dns.promises API 提供另一組非同步 DNS 方法,這些方法會傳回 Promise 物件,而不是使用回呼函式。可透過 require('node:dns').promisesrequire('node:dns/promises') 存取此 API。

類別:dnsPromises.Resolver#

DNS 要求的獨立解析器。

建立新的解析器會使用預設伺服器設定。使用 resolver.setServers() 設定解析器所使用的伺服器,不會影響其他解析器

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

// This request will use the server at 4.4.4.4, independent of global settings.
resolver.resolve4('example.org').then((addresses) => {
  // ...
});

// Alternatively, the same code can be written using async-await style.
(async function() {
  const addresses = await resolver.resolve4('example.org');
})(); 

dnsPromises API 提供下列方法

resolver.cancel()#

取消此解析器所做的所有未完成 DNS 查詢。對應的承諾會以代碼 ECANCELLED 的錯誤拒絕。

dnsPromises.getServers()#

傳回目前設定用於 DNS 解析的 IP 位址字串陣列,格式符合 RFC 5952。如果使用自訂埠,字串將包含埠區段。

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

dnsPromises.lookup(hostname[, options])#

  • hostname <string>
  • options <integer> | <Object>
    • family <integer> 記錄家族。必須為 460。值 0 表示傳回 IPv4 或 IPv6 位址。如果值 0{ all: true }(見下方)一起使用,則會傳回 IPv4 和 IPv6 位址。預設:0
    • hints <數字> 一個或多個 支援的 getaddrinfo 旗標。多個旗標可以透過按位元 OR 其值來傳遞。
    • all <boolean> 當為 true 時,Promise 會以陣列中的所有位址解決。否則,傳回單一位址。預設:false
    • verbatim <boolean> 當為 true 時,Promise 會以 DNS 解析器傳回的順序,解決 IPv4 和 IPv6 位址。當為 false 時,IPv4 位址會置於 IPv6 位址之前。預設:目前為 false(位址會重新排序),但預計在不久的將來會變更。預設值可使用 dns.setDefaultResultOrder()--dns-result-order 設定。新程式碼應使用 { verbatim: true }

將主機名稱(例如 'nodejs.org')解析為找到的第一個 A (IPv4) 或 AAAA (IPv6) 記錄。所有 option 屬性都是選用的。如果 options 是整數,則必須為 46 – 如果未提供 options,則如果找到,會傳回 IPv4 和 IPv6 位址。

all 選項設定為 true 時,Promise 會以 addresses 解析為具有 addressfamily 屬性的物件陣列。

發生錯誤時,Promise 會以 Error 物件為基準拒絕,其中 err.code 為錯誤碼。請記住,err.code 不僅會在主機名稱不存在時設定為 'ENOTFOUND',也會在查詢以其他方式失敗時設定,例如沒有可用的檔案描述符。

dnsPromises.lookup() 不一定與 DNS 協定有關。實作使用作業系統設施,可以將名稱與位址關聯,反之亦然。這個實作可能會對任何 Node.js 程式產生微妙但重要的影響。請在使用 dnsPromises.lookup() 之前花點時間參閱 實作考量部分

範例用法

const dns = require('node: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
});

// When options.all is true, the result will be an Array.
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 實作,將指定的 addressport 解析成主機名稱和服務。

如果 address 不是有效的 IP 位址,將會擲回 TypeErrorport 會強制轉換成數字。如果它不是合法的埠號,將會擲回 TypeError

發生錯誤時,Promise 會以 Error 物件為基準拒絕,其中 err.code 為錯誤碼。

const dnsPromises = require('node: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> 要解析的主機名稱。
  • rrtype <string> 資源記錄類型。預設:'A'

使用 DNS 協定將主機名稱(例如 'nodejs.org')解析成資源記錄陣列。成功時,Promise 會以資源記錄陣列為基準解決。個別結果的類型和結構會根據 rrtype 而有所不同

rrtyperecords 包含結果類型簡寫方法
'A'IPv4 位址(預設)<string>dnsPromises.resolve4()
'AAAA'IPv6 位址<string>dnsPromises.resolve6()
'ANY'任何記錄<Object>dnsPromises.resolveAny()
'CAA'CA 授權記錄<Object>dnsPromises.resolveCaa()
'CNAME'正規名稱記錄<string>dnsPromises.resolveCname()
'MX'郵件交換記錄<Object>dnsPromises.resolveMx()
'NAPTR'名稱授權指標記錄<Object>dnsPromises.resolveNaptr()
'NS'名稱伺服器記錄<string>dnsPromises.resolveNs()
'PTR'指標記錄<string>dnsPromises.resolvePtr()
「SOA」權限記錄的開頭<Object>dnsPromises.resolveSoa()
「SRV」服務記錄<Object>dnsPromises.resolveSrv()
「TXT」文字記錄<string[]>dnsPromises.resolveTxt()

如果發生錯誤,Promise 會以 Error 物件拒絕,其中 err.codeDNS 錯誤代碼 之一。

dnsPromises.resolve4(hostname[, options])#

  • hostname <string> 要解析的主機名稱。
  • options <Object>
    • ttl <boolean> 擷取每筆記錄的時間生存期 (TTL) 值。如果為 truePromise 會以 { address: '1.2.3.4', ttl: 60 } 物件陣列解決,而不是字串陣列,其中 TTL 以秒為單位表示。

使用 DNS 協定為 hostname 解決 IPv4 位址 (A 記錄)。如果成功,Promise 會以 IPv4 位址陣列解決 (例如 ['74.125.79.104', '74.125.79.105', '74.125.79.106'])。

dnsPromises.resolve6(hostname[, options])#

  • hostname <string> 要解析的主機名稱。
  • options <Object>
    • ttl <boolean> 擷取每筆記錄的時間生存期 (TTL) 值。如果為 truePromise 會以 { address: '0:1:2:3:4:5:6:7', ttl: 60 } 物件陣列解決,而不是字串陣列,其中 TTL 以秒為單位表示。

使用 DNS 協定為 hostname 解決 IPv6 位址 (AAAA 記錄)。如果成功,Promise 會以 IPv6 位址陣列解決。

dnsPromises.resolveAny(hostname)#

使用 DNS 協定解析所有記錄(也稱為 ANY* 查詢)。如果成功,Promise 會以包含各種記錄類型的陣列來解析。每個物件都有 type 屬性,用來表示目前記錄的類型。而且根據 type,物件上會存在其他屬性

類型屬性
'A'address/ttl
'AAAA'address/ttl
'CNAME'
'MX'請參閱 dnsPromises.resolveMx()
'NAPTR'請參閱 dnsPromises.resolveNaptr()
'NS'
'PTR'
「SOA」請參閱 dnsPromises.resolveSoa()
「SRV」請參閱 dnsPromises.resolveSrv()
「TXT」這種類型的記錄包含稱為 entries 的陣列屬性,它指的是 dnsPromises.resolveTxt(),例如 { entries: ['...'], type: 'TXT' }

以下是結果物件範例

[ { 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.resolveCaa(hostname)#

使用 DNS 協定解析 hostnameCAA 記錄。如果成功,Promise 會以物件陣列來解析,這些物件包含可供 hostname 使用的認證機構授權記錄(例如 [{critical: 0, iodef: 'mailto:[email protected]'},{critical: 128, issue: 'pki.example.com'}])。

dnsPromises.resolveCname(hostname)#

使用 DNS 協定解析 hostnameCNAME 記錄。如果成功,Promise 會解析為 hostname 可用的標準名稱記錄陣列(例如 ['bar.example.com'])。

dnsPromises.resolveMx(hostname)#

使用 DNS 協定解析 hostname 的郵件交換記錄(MX 記錄)。如果成功,Promise 會解析為包含 priorityexchange 屬性的物件陣列(例如 [{priority: 10, exchange: 'mx.example.com'}, ...])。

dnsPromises.resolveNaptr(hostname)#

使用 DNS 協定解析 hostname 的基於正規表示式的記錄(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)#

使用 DNS 協定解析 hostname 的名稱伺服器記錄(NS 記錄)。如果成功,Promise 會解析為 hostname 可用的名稱伺服器記錄陣列(例如 ['ns1.example.com', 'ns2.example.com'])。

dnsPromises.resolvePtr(hostname)#

使用 DNS 協定解析 hostname 的指標記錄(PTR 記錄)。如果成功,Promise 會解析為包含回覆記錄的字串陣列。

dnsPromises.resolveSoa(hostname)#

使用 DNS 協定來解析權威記錄的開頭 (SOA 記錄) for hostname。成功時,Promise 會以具有下列屬性的物件解析

  • nsname
  • hostmaster
  • serial
  • refresh
  • 重試
  • 過期
  • 最小生存時間
{
  nsname: 'ns.example.com',
  hostmaster: 'root.example.com',
  serial: 2013101809,
  refresh: 10000,
  retry: 2400,
  expire: 604800,
  minttl: 3600
} 

dnsPromises.resolveSrv(hostname)#

使用 DNS 協定來解析服務記錄 (SRV 記錄) for hostname。成功時,Promise 會以具有下列屬性的物件陣列解析

  • 優先順序
  • 權重
  • 名稱
{
  priority: 10,
  weight: 5,
  port: 21223,
  name: 'service.example.com'
} 

dnsPromises.resolveTxt(hostname)#

使用 DNS 協定來解析文字查詢 (TXT 記錄) for hostname。成功時,Promise 會以 hostname 可用的文字記錄的二維陣列解析 (例如 [ ['v=spf1 ip4:0.0.0.0 ', '~all' ] ])。每個子陣列包含一個記錄的 TXT 塊。根據使用案例,這些塊可以合併在一起或個別處理。

dnsPromises.reverse(ip)#

執行反向 DNS 查詢,將 IPv4 或 IPv6 位址解析為一組主機名稱。

如果發生錯誤,Promise 會以 Error 物件拒絕,其中 err.codeDNS 錯誤代碼 之一。

dnsPromises.setDefaultResultOrder(order)#

  • order <string> 必須是 'ipv4first''verbatim'

dns.lookup()dnsPromises.lookup() 中設定 verbatim 的預設值。值可以是

  • ipv4first:設定預設 verbatimfalse
  • verbatim:設定預設 verbatimtrue

預設為 verbatim,而 dnsPromises.setDefaultResultOrder() 的優先權高於 --dns-result-order。當使用 工作執行緒 時,主執行緒的 dnsPromises.setDefaultResultOrder() 函式不會影響工作執行緒中的預設 DNS 順序。

dnsPromises.getDefaultResultOrder()#

取得 dnsOrder 的值。

dnsPromises.setServers(servers)#

設定執行 DNS 解析時要使用的伺服器 IP 位址和埠號。servers 參數是 RFC 5952 格式位址的陣列。如果埠號是 IANA 預設 DNS 埠號 (53),則可以省略。

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

如果提供無效的位址,將擲回錯誤。

dnsPromises.setServers() 方法不得在 DNS 查詢進行期間呼叫。

此方法的運作方式與 resolve.conf 非常類似。也就是說,如果嘗試使用提供的第 1 個伺服器解析,但結果為 NOTFOUND 錯誤,resolve() 方法不會嘗試使用後續提供的伺服器進行解析。只有在較早的伺服器逾時或導致其他錯誤時,才會使用備用 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:指定非法提示旗標。
  • dns.NOTINITIALIZED:尚未執行 c-ares 函式庫初始化。
  • dns.LOADIPHLPAPI:載入 iphlpapi.dll 時發生錯誤。
  • dns.ADDRGETNETWORKPARAMS:找不到 GetNetworkParams 函式。
  • dns.CANCELLED:DNS 查詢已取消。

dnsPromises API 也會匯出上述錯誤碼,例如 dnsPromises.NODATA

實作考量#

儘管 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() 會是非同步的,但它實作為對 getaddrinfo(3) 的同步呼叫,而此呼叫會在 libuv 的執行緒池上執行。這可能會對某些應用程式產生令人驚訝的負面效能影響,請參閱 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 中的組態。