IO.js DNS

2018-11-28 22:33 更新

穩(wěn)定度: 2 - 穩(wěn)定

通過require('dns')來獲取這個模塊。

這個模塊包含以下兩類函數(shù):

1) 使用底層操作系統(tǒng)工具來進行域名解析的函數(shù),并且不需要進行任何網(wǎng)絡(luò)活動。這類函數(shù)只有一個:dns.lookup。希望與 在其他操作系統(tǒng)的其他應(yīng)用 執(zhí)行域名解析 有相同行為時,請使用dns.lookup。

下面是一個解析www.google.com的例子:

var dns = require('dns');

dns.lookup('www.google.com', function onLookup(err, addresses, family) {
  console.log('addresses:', addresses);
});

2) 連接實際的DNS服務(wù)器來進行域名解析的函數(shù),并且經(jīng)常使用網(wǎng)絡(luò)來執(zhí)行DNS查找。除了dns.lookupDNS模塊的所有函數(shù)都屬于這類。這類函數(shù)不與dns.lookup使用相同的配置文件。例如,它們不使用/etc/hosts配置文件。這類函數(shù)適合那些不希望使用底層操作系統(tǒng)工具來進行域名解析,總是想要執(zhí)行DNS查詢的開發(fā)者。

下面例子是,解析'www.google.com',然后反向解析返回的IP地址。

var dns = require('dns');

dns.resolve4('www.google.com', function (err, addresses) {
  if (err) throw err;

  console.log('addresses: ' + JSON.stringify(addresses));

  addresses.forEach(function (a) {
    dns.reverse(a, function (err, hostnames) {
      if (err) {
        throw err;
      }

      console.log('reverse for ' + a + ': ' + JSON.stringify(hostnames));
    });
  });
});

兩者之間的選擇會產(chǎn)生微妙的結(jié)果,更多信息請查詢下文實現(xiàn)注意事項章節(jié)。

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

解析hostname(如'google.com')為第一個找到的A(IPv4)或AAAA(IPv6)記錄。options可以是對象或者數(shù)組。如果options沒有提供,那么IPv4和IPv6都是有效的。如果options是一個數(shù)組,那么它必須是46

另外,options可以是一個含有以下屬性的對象:

  • family: {Number} - 地址族。如果提供,必須為整數(shù)46。如果沒有提供,那么IPv4和IPv6都是有效的。
  • hints: {Number} - 如果提供,它必須是一個或多個支持的getaddrinfo標識。如果沒有提供,那么沒有標識被傳遞給getaddrinfo。多個標識可以通過在邏輯上ORing它們的值,來傳遞給hints。支持的getaddrinfo標識請參閱下文。
  • all: {Boolean} - 如果true,那么回調(diào)函數(shù)以數(shù)組的形式返回所有解析的地址,否則只返回一個地址。默認為false。

所有的屬性都是可選的,以下是一個options例子:

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

回調(diào)函數(shù)有參數(shù)(err, address, family)。address是IPv4或IPv6地址字符串。familyadress的協(xié)議族,即46。

如果options的所有參數(shù)都被設(shè)置,那么參數(shù)轉(zhuǎn)變?yōu)椋╡rr, addresses),addresses是一個地址和協(xié)議族數(shù)組。

若發(fā)生錯誤,err是錯誤對象,err.code是錯誤碼。不僅在hostname不存在時,在如沒有可用的文件描述符等情況下查找失敗,err.code也會被設(shè)置為'ENOENT'

dns.lookup不需要與DNS協(xié)議有任何關(guān)系。它僅僅是一個連接名字和地址的操作系統(tǒng)功能。

在任何的io.js程序中,它的實現(xiàn)對表現(xiàn)有一些微妙但是重要的影響。在使用前,請花一些時間查閱實現(xiàn)注意事項章節(jié)。

dns.lookupService(address, port, callback)

解析給定的addressport為一個主機名和使用getnameinfo的服務(wù)。

回調(diào)函數(shù)有參數(shù)(err, hostname, service)。hostnameservice參數(shù)是字符串(如分別為'localhost''http')。

若發(fā)生錯誤,err是錯誤對象,err.code是錯誤碼。

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

使用指定的rrtype類型,解析主機名(如'google.com')為一個記錄數(shù)組。

有效的rrtype有:

  • 'A' (IPV4 地址,默認)
  • 'AAAA' (IPV6 地址)
  • 'MX' (郵件交換記錄)
  • 'TXT' (文本記錄)
  • 'SRV' (SRV記錄)
  • 'PTR' (用于IP反向查找)
  • 'NS' (域名服務(wù)器記錄)
  • 'CNAME' (別名記錄)
  • 'SOA' (權(quán)限開始記錄)

回調(diào)函數(shù)有參數(shù)(err, addresses)。address中每個元素的類型由記錄類型所指定,并且在下文相應(yīng)的查找方法中有描述。

若發(fā)生錯誤,err是錯誤對象,err.code是下文錯誤代碼列表中的一個。

dns.resolve4(hostname, callback)

dns.resolve()相同,但只使用IPv4查詢(一個記錄)。地址是一個IPv4地址數(shù)組(如['74.125.79.104', '74.125.79.105', '74.125.79.106'])。

dns.resolve6(hostname, callback)

dns.resolve4()相同,除了使用IPv6查詢(一個AAAA查詢)。

dns.resolveMx(hostname, callback)

dns.resolve()相同,但是只用于郵件交換查詢(MX記錄)。

地址是一個MX記錄數(shù)組,每一個元素都有一個priority和一個exchange屬性(如[{'priority': 10, 'exchange': 'mx.example.com'},...])。

dns.resolveTxt(hostname, callback)

dns.resolve()相同,但是只用于文本查詢(TXT記錄)。地址是一個hostname可用的2-d數(shù)組(如[ ['v=spf1 ip4:0.0.0.0 ', '~all' ] ])。每個字數(shù)組包含一個記錄的TXT數(shù)據(jù)塊。根據(jù)使用場景的不同,它們可能被連接在一起也可能被分開。

dns.resolveSrv(hostname, callback)

dns.resolve()相同,但是只用于服務(wù)查詢(SRV記錄)。地址是一個hostname可用的SRV記錄數(shù)組。SRV記錄的屬性有priority,weight,port,和name(如[{'priority': 10, 'weight': 5, 'port': 21223, 'name': 'service.example.com'}, ...])。

dns.resolveSoa(hostname, callback)

dns.resolve()相同,但是只用于權(quán)限記錄查詢(SOA記錄)。

地址是一個有以下結(jié)構(gòu)的對象:

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

dns.resolveNs(hostname, callback)

dns.resolve()相同,但是只用于域名服務(wù)器查詢(NS記錄)。地址是一個hostname可用的域名服務(wù)器記錄數(shù)組(如['ns1.example.com', 'ns2.example.com'])。

dns.resolveCname(hostname, callback)

dns.resolve()相同,但是只用于別名記錄(別名記錄)。地址是一個hostname可用的別名數(shù)組(如['bar.example.com'])。

dns.reverse(ip, callback)

為得到一個主機名數(shù)組,反向查詢一個IP。

回調(diào)函數(shù)有參數(shù)(err, hostnames)。

若發(fā)生錯誤,err是錯誤對象,err.code是下文錯誤代碼列表中的一個。

dns.getServers()

返回一個正在被用于解析的IP地址字符串數(shù)組。

dns.setServers(servers)

給定一個IP地址字符串數(shù)組,將它們設(shè)置給用來解析的服務(wù)器。

如果你為地址指定了一個端口,端口會被忽略,因為底層庫不支持。

如果你傳遞了非法輸入,會拋出錯誤。

Error codes

每一次DNS查詢都可能返回以下錯誤碼之一:

  • dns.NODATA: DNS服務(wù)器返回一個沒有數(shù)據(jù)的應(yīng)答。
  • dns.FORMERR: DNS服務(wù)器聲明查詢是格式錯誤的。
  • dns.SERVFAIL: DNS服務(wù)器返回一個普通錯誤。
  • dns.NOTFOUND: 域名沒有找到。
  • dns.NOTIMP: DNS服務(wù)器沒有實現(xiàn)請求的操作。
  • dns.REFUSED: DNS服務(wù)器拒絕查詢。
  • dns.BADQUERY: 格式錯誤的DNS查詢。
  • dns.BADNAME: 格式錯誤的主機名。
  • dns.BADFAMILY: 不支持的協(xié)議族。
  • dns.BADRESP: 格式錯誤的DNS響應(yīng)。
  • dns.CONNREFUSED: 不能連接到DNS服務(wù)器。
  • dns.TIMEOUT: 連接DNS服務(wù)器超時。
  • dns.EOF: 文件末端。
  • dns.FILE: 讀取文件錯誤。
  • dns.NOMEM: 內(nèi)存溢出。
  • dns.DESTRUCTION: 通道被銷毀。
  • dns.BADSTR: 格式錯誤的字符串。
  • dns.BADFLAGS: 指定了非法標志。
  • dns.NONAME: 給定的主機名不是數(shù)字。
  • dns.BADHINTS: 給定的提示標識非法。
  • dns.NOTINITIALIZED: c-ares庫初始化未被執(zhí)行。
  • dns.LOADIPHLPAPI: 加載iphlpapi.dll錯誤。
  • dns.ADDRGETNETWORKPARAMS: 找不到GetNetworkParams函數(shù)。
  • dns.CANCELLED: DNS查詢被取消。

支持的getaddrinfo標識

以下標識可以被傳遞給dns.lookuphints

  • dns.ADDRCONFIG: 返回的地址類型由當前系統(tǒng)支持的地址類型決定。例如,如果當前系統(tǒng)至少有一個IPv4地址被配置,那么將只會返回IPv4地址。回溯地址不被考慮。
  • dns.V4MAPPED: 如果IPv6協(xié)議族被指定,但是沒有發(fā)現(xiàn)IPv6地址,那么返回IPv6地址的IPv4映射。

實現(xiàn)注意事項

盡管dns.lookupdns.resolve*/dns.reverse函數(shù)都用于關(guān)聯(lián)一個域名和一個地址(或反之亦然),它們的行為還是有些許區(qū)別。這些差別雖然微小,但是對于io.js程序的行為有重大影響。

dns.lookup

在引擎下,dns.lookup使用了和其他程序相同的操作系統(tǒng)功能。例如,dns.lookup將總是和ping命令一樣解析一個給定的域名。在大多類POSIX操作系統(tǒng)上,dns.lookup函數(shù)的表現(xiàn)可以通過改變nsswitch.conf(5) 和/或 resolv.conf(5)的設(shè)置來調(diào)整,但是需要小心的是,改變這些文件將會影響這個操作系統(tǒng)上正在運行的所有其他程序。

雖然在JavaScript的角度,這個調(diào)用是異步的,但是它在libuv線程池中的實現(xiàn)是同步調(diào)用getaddrinfo(3)。因為libuv線程池有一個固定的大小,意味著如果getaddrinfo(3)花費了太多的時間,那么其他libuv線程池中的操作(如文件系統(tǒng)操作)會感覺到性能下降。為了緩解這個情況,一個潛在的解決方案是通過設(shè)置'UV_THREADPOOL_SIZE'環(huán)境變量大于4(當前默認值)來增加libuv線程池的大小。更多l(xiāng)ibuv線程池的信息,請參閱官方的libuv文檔。

dns.resolve,以dns.resolve和dns.reverse開頭的函數(shù)

這些函數(shù)的實現(xiàn)與dns.lookup相當不同。它們不使用getaddrinfo(3)并且它們總是通過網(wǎng)絡(luò)執(zhí)行一次DNS查詢。這些網(wǎng)絡(luò)通信通常是異步的,并且不使用libuv線程池。

作為結(jié)果,其他使用libuv線程池的dns.lookup方法的進程可能會有相同的負面影響,但這些函數(shù)沒有。

它們與dns.lookup使用了不同的配置文件。例如,它們不使用/etc/hosts中的配置。

以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號