Node.js API詳解之 dns模塊用法實(shí)例分析
本文實(shí)例講述了Node.js API詳解之 dns模塊用法。分享給大家供大家參考,具體如下:
Node.js API詳解之 dns
dns (域名服務(wù)器)模塊包含兩類函數(shù):
第一類函數(shù),使用底層操作系統(tǒng)工具進(jìn)行域名解析,且無需進(jìn)行網(wǎng)絡(luò)通信。 這類函數(shù)只有一個(gè):dns.lookup()。
例子,查找 baidu.com:
const dns = require('dns');
dns.lookup('www.baidu.com', (err, address, family) => {
console.log('IP 地址: %j 地址族: IPv%s', address, family);
});
// IP 地址: "180.149.131.98" 地址族: IPv4
第二類函數(shù),連接到一個(gè)真實(shí)的 DNS 服務(wù)器進(jìn)行域名解析,且始終使用網(wǎng)絡(luò)進(jìn)行 DNS 查詢。
這類函數(shù)包含了 dns 模塊中除 dns.lookup() 以外的所有函數(shù)。
這些函數(shù)使用與 dns.lookup() 不同的配置文件(例如 /etc/hosts)。
這類函數(shù)適合于那些不想使用底層操作系統(tǒng)工具進(jìn)行域名解析、而是想使用網(wǎng)絡(luò)進(jìn)行 DNS 查詢的開發(fā)者。
例子,解析 ‘a(chǎn)rchive.org' 然后逆向解析返回的 IP 地址:
const dns = require('dns');
dns.resolve4('archive.org', (err, addresses) => {
if (err) throw err;
console.log(`IP 地址: ${JSON.stringify(addresses)}`);
addresses.forEach((a) => {
dns.reverse(a, (err, hostnames) => {
if (err) {
throw err;
}
console.log(`IP 地址 ${a} 逆向解析到域名: ${JSON.stringify(hostnames)}`);
});
});
});
// IP 地址: ["207.241.224.2"]
// IP 地址 207.241.224.2 逆向解析到域名: ["www.archive.org"]
dns.getServers()
說明:
返回一個(gè)用于當(dāng)前DNF解析的IP地址的數(shù)組的字符串,格式根據(jù)rfc5952。
如果使用自定義端口,那么字符串將包括一個(gè)端口部分。
demo:
const dns= require('dns');
console.log( dns.getServers() );
// [ '172.116.20.254', '127.0.0.1' ]
dns.setServers(servers)
說明:
設(shè)置IP地址服務(wù)器端口在進(jìn)行DNS解析時(shí)可用,servers參數(shù)是一個(gè)rfc5952數(shù)組格式的地址。
如果端口是IANA默認(rèn)端口(53),那么它可以被忽略。
demo:
const dns = require('dns');
dns.setServers([ '172.116.20.254', '127.1.1.1' ])
console.log( dns.getServers() );
// [ '172.116.20.254', '127.1.1.1' ]
dns.lookup(hostname[, options], callback)
說明:
解析hostname(例如:'nodejs.org')第一個(gè)找到的A(IPv4)或AAAA(IPv6)記錄。
options可以是對(duì)象或者整數(shù)。如果options沒有被提供,那么IPv4 和 IPv6都是有效的。如果options是整數(shù),只能是4或6。
另外,options可以是一個(gè)含有以下屬性的對(duì)象:
family: T地址族。如果提供,必須為整數(shù)4或6。如果沒有提供,只接受IPv4和IPv6地址。
all:值為true時(shí), 回調(diào)函數(shù)返回一個(gè)包含所有解析后地址的數(shù)組,否則只返回一個(gè)地址。默認(rèn)值為false
hints:如果提供,它必須是一個(gè)或多個(gè)支持的getaddrinfo標(biāo)識(shí)。如果沒有提供,那么沒有標(biāo)識(shí)被傳遞給getaddrinfo。
多個(gè)標(biāo)識(shí)可以通過在邏輯上ORing它們的值,來傳遞給hints。支持的getaddrinfo標(biāo)識(shí):
dns.ADDRCONFIG: 返回當(dāng)前系統(tǒng)支持的地址類型。例如,如果當(dāng)前系統(tǒng)至少配置了一個(gè) IPv4 地址,則返回 IPv4地址。不考慮回環(huán)地址。
dns.V4MAPPED: 如果指定了 IPv6 家族, 但是沒有找到 IPv6 地址,將返回 IPv4 映射的 IPv6地址。在有些操作系統(tǒng)中不支持(e.g FreeBSD 10.1)。
回調(diào)函數(shù)包含(err, address, family)參數(shù)。
address是IPv4或IPv6地址字符串。
family、是整數(shù)4或6,表示地址族(不一定是最初傳遞給查找的值)。
當(dāng)all屬性被設(shè)置為true時(shí),回調(diào)函數(shù)參數(shù)變?yōu)?err, addresses),addresses則變成一個(gè)由address 和 family 屬性組成的對(duì)象數(shù)組。
dns.lookup() 不需要與DNS協(xié)議有任何關(guān)系。它僅僅是一個(gè)連接名字和地址的操作系統(tǒng)功能。
在任何的node.js程序中,它的實(shí)現(xiàn)對(duì)表現(xiàn)有一些微妙但是重要的影響。
盡管dns.lookup()和各種dns.resolve *()/ dns.reverse()函數(shù)有相同的目標(biāo)將網(wǎng)絡(luò)的名字與網(wǎng)絡(luò)地址聯(lián)系在一起(反之亦然),
他們的行為是完全不同的。 這些差異可以有微妙但重大影響著Node.js程序行為。
demo:
const dns = require('dns');
const options = {
family: 6,
hints: dns.ADDRCONFIG | dns.V4MAPPED,
};
dns.lookup('nodejs.cn', options, (err, address, family) =>
console.log('address: %j family: IPv%s', address, family));
// address: "::ffff:112.124.39.54" family: IPv6
options.all = true;
dns.lookup('nodejs.cn', options, (err, addresses) =>
console.log('addresses: %j', addresses));
// addresses: [{"address":"::ffff:112.124.39.54","family":6}]
dns.lookupService(address, port, callback)
說明:
將參數(shù)address和port傳入操作系統(tǒng)底層getnameinfo服務(wù)來解析處理并返回主機(jī)名。
如果address不是有效的IP地址,會(huì)拋出TypeError。port必須是一個(gè)整數(shù).如果不是規(guī)定的端口號(hào),會(huì)拋出TypeError.
出錯(cuò)情況下,err是一個(gè)Error對(duì)象,err.code代碼錯(cuò)誤碼。
demo:
const dns = require('dns');
dns.lookupService('127.0.0.1', 22, (err, hostname, service) => {
console.log(hostname, service);
// localhost ssh
});
dns.reverse(ip, callback)
說明:
執(zhí)行一個(gè)反向DNS查詢返回IPv4或IPv6地址的主機(jī)名的數(shù)組。
demo:
const dns = require('dns');
dns.reverse('101.20.17.16', (err, hostname) => {
console.log(hostname);
});
dns.Resolver 類
說明:
DNS請(qǐng)求的獨(dú)立解析程序。
使用默認(rèn)的設(shè)置創(chuàng)建一個(gè)新的解析程序。
為一個(gè)解析程序設(shè)置servers使用resolver.setServers(),它不會(huì)影響其他的解析程序:
demo:
const { Resolver } = require('dns');
const resolver = new Resolver();
resolver.setServers(['4.4.4.4']);
resolver.resolve4('baidu.com', (err, addresses) => {
console.log(addresses);
});
resolver.cancel()
說明:
取消這個(gè)解析程序的未解決的DNS查詢,相應(yīng)的回調(diào)用一個(gè)ECANCELLED碼調(diào)用。
demo:
const { Resolver } = require('dns');
const resolver = new Resolver();
resolver.setServers(['4.4.4.4']);
resolver.resolve4('baidu.com', (err, addresses) => {
console.log(addresses);
});
resolver.cancel();
dns.resolve(hostname[, rrtype], callback)
說明:
hostname:解析的主機(jī)名。
rrtype:資源記錄類型. 默認(rèn): ‘A'.c
使用DNS協(xié)議來解析一個(gè)主機(jī)名(e.g. ‘nodejs.org')為一個(gè)資源記錄的數(shù)組。
回調(diào)函數(shù)的參數(shù)為(err, records)。當(dāng)成功時(shí),records將是一個(gè)資源記錄的數(shù)組。它的類型和結(jié)構(gòu)取決于rrtype。
下面是不同rrtype對(duì)應(yīng)resolve的快捷方法:

demo:
const dns = require('dns');
dns.resolve('archive.org', 'A', (err, addresses) => {
if (err) throw err;
console.log(`IP 地址: ${JSON.stringify(addresses)}`);
});
// IP 地址: ["207.241.224.2"]
dns.resolve4(hostname[, options], callback)
說明:
使用DNS協(xié)議解析IPv4地址主機(jī)名(A記錄)。
adresses參數(shù)是傳遞給callback函數(shù)的IPv4地址數(shù)組。(例如:[‘74.125.79.104', ‘74.125.79.105', ‘74.125.79.106'])
hostname:需要解析的主機(jī)名
options.ttl:記錄每一條記錄的存活次數(shù) (TTL)。如果為 true, 返回的結(jié)果將會(huì)為 Object 的數(shù)組,就像 { address: ‘1.2.3.4', ttl: 60 } 帶有 TTL 秒數(shù)的記錄,而不是 string 的數(shù)組.
demo:
const dns = require('dns');
dns.resolve4('archive.org', {ttl: true}, (err, addresses) => {
if (err) throw err;
console.log(`IPv4地址數(shù)組: ${JSON.stringify(addresses)}`);
});
// IPv4地址數(shù)組: [{"address":"207.241.224.2","ttl":58}]
dns.resolve6(hostname[, options], callback)
說明:
使用DNS協(xié)議解析IPv6地址主機(jī)名(AAAA記錄)。
adresses參數(shù)是傳遞給callback函數(shù)的IPv6地址數(shù)組.
demo:
const dns = require('dns');
dns.resolve6('www.taobao.com', {ttl: true}, (err, addresses) => {
if (err) throw err;
console.log(`IPv6地址主機(jī)名: ${JSON.stringify(addresses)}`);
});
// IPv6地址主機(jī)名: []
dns.resolveCname(hostname, callback)
說明:
使用DNS協(xié)議解析CNAME記錄主機(jī)名。
adresses參數(shù)是傳遞給callback函數(shù)規(guī)范內(nèi)有效的主機(jī)名數(shù)組(例如:[‘bar.example.com']).
demo:
const dns = require('dns');
dns.resolveCname('www.taobao.com', (err, addresses) => {
if (err) throw err;
console.log(`CNAME記錄主機(jī)名: ${JSON.stringify(addresses)}`);
});
// CNAME記錄主機(jī)名: ["www.taobao.com.danuoyi.tbcache.com"]
dns.resolveMx(hostname, callback)
說明:
使用DNS協(xié)議處理郵件交換記錄主機(jī)名(MX記錄)。
adresses參數(shù)是傳遞給callback函數(shù)的主機(jī)名對(duì)象數(shù)組,對(duì)
象包含priority和exchange屬性(例如: [{priority: 10, exchange: ‘mx.example.com'}, …])。
demo:
const dns = require('dns');
dns.resolveMx('mail.qq.com', (err, addresses) => {
if (err) throw err;
console.log(`MX記錄: ${JSON.stringify(addresses)}`);
});
dns.resolveNaptr(hostname, callback)
說明:
使用DNS協(xié)議來處理基于正則表達(dá)式匹配的記錄(NAPTR記錄)的主機(jī)名。
adresses參數(shù)是傳遞給callback函數(shù)的主機(jī)名對(duì)象數(shù)組,對(duì)象包含屬性:
flags
service
regexp
replacement
order
preference
demo:
const dns = require('dns');
dns.resolveNaptr('www.taobao.com', (err, addresses) => {
if (err) throw err;
console.log(`NAPTR記錄: ${JSON.stringify(addresses)}`);
});
dns.resolveNs(hostname, callback)
說明:
使用DNS協(xié)議處理名稱服務(wù)器主機(jī)名記錄(NS記錄)。
adresses為有效的名稱服務(wù)器記錄主機(jī)名數(shù)組(eg:[‘ns1.example.com', ‘ns2.example.com'])。
demo:
const dns = require('dns');
dns.resolveNs('www.taobao.com', (err, addresses) => {
if (err) throw err;
console.log(`NS記錄: ${JSON.stringify(addresses)}`);
});
dns.resolvePtr(hostname, callback)
說明:
使用DNS協(xié)議處理主機(jī)名引用記錄(PTR記錄)。
addresses參數(shù)將一個(gè)字符串?dāng)?shù)組傳遞給回調(diào)函數(shù)callback,其中包含回復(fù)記錄。
demo:
const dns = require('dns');
dns.resolvePtr('www.taobao.com', (err, addresses) => {
if (err) throw err;
console.log(`PTR記錄: ${JSON.stringify(addresses)}`);
});
dns.resolveSoa(hostname, callback)
說明:
使用DNS協(xié)議處理主機(jī)名子域名記錄(SOA記錄)。addresses參數(shù)為一個(gè)對(duì)象包含以下屬性:
nsname
hostmaster
serial
refresh
retry
expire
minttl
demo:
const dns = require('dns');
dns.resolveSoa('www.taobao.com', (err, addresses) => {
if (err) throw err;
console.log(`SOA記錄: ${JSON.stringify(addresses)}`);
});
dns.resolveSrv(hostname, callback)
說明:
使用DNS協(xié)議來處理主機(jī)名服務(wù)記錄(SRV記錄)。
callback函數(shù)返回的addresses參數(shù)為對(duì)象數(shù)組,每個(gè)對(duì)象包含以下屬性:
priority
weight
port
name
demo:
const dns = require('dns');
dns.resolveSrv('www.taobao.com', (err, addresses) => {
if (err) throw err;
console.log(`SRV記錄: ${JSON.stringify(addresses)}`);
});
dns.resolveTxt(hostname, callback)
說明:
使用DNS協(xié)議處理文本查詢主機(jī)名(TXT記錄)?;卣{(diào)函數(shù)callback會(huì)返回records參數(shù),
它是一個(gè)文本記錄與主機(jī)名一一對(duì)應(yīng)的二維數(shù)組(例如:[ [‘v=spf1 ip4:0.0.0.0 ‘, ‘~all' ] ]).
每個(gè)數(shù)組文本塊包含一條記錄。根據(jù)用例,這些可以是連接在一起或單獨(dú)對(duì)待。
demo:
const dns = require('dns');
dns.resolveTxt('www.taobao.com', (err, addresses) => {
if (err) throw err;
console.log(`TXT記錄: ${JSON.stringify(addresses)}`);
});
dns.resolveAny(hostname, callback)
說明:
使用DNS協(xié)議解析所有記錄。
callback函數(shù)的參數(shù)將是一個(gè)包含各種類型記錄的數(shù)組。每個(gè)對(duì)象都有一個(gè)屬性type,指示當(dāng)前記錄的類型。
“A”、”AAAA”、”CNAME”、”MX”、”NAPTR”、”NS”、”PTR”、”SOA”、”SRV”、”TXT”等
demo:
const dns = require('dns');
dns.resolveAny('www.taobao.com', (err, addresses) => {
if (err) throw err;
console.log(`${JSON.stringify(addresses)}`);
});
// [ { 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 } ]
錯(cuò)誤碼
說明:
每個(gè)DNS查詢可以返回一個(gè)錯(cuò)誤代碼如下:
dns.NODATA:DNS服務(wù)返回沒有數(shù)據(jù)。
dns.FORMERR:DNS服務(wù)器查詢沒有格式化。
dns.SERVFAIL:DNS服務(wù)器返回失敗。
dns.NOTFOUND:域名未找到。
dns.NOIMP:DNS服務(wù)器不執(zhí)行請(qǐng)求的操作。
dns.REFUSED:查詢DNS服務(wù)器拒絕。
dns.BADQUERY:未格式化DNS查詢。
dns.BADNAME:未格式化主機(jī)名
dns.BADFAMILY:沒有提供地址族
dns.BADRESP:未格式化DNS回復(fù)
dns.CONNREFUSED:無法連接DNS服務(wù)器
dns.TIMEOUT:連接DNS服務(wù)器超時(shí)
dns.EOF:文件末尾
dns.FILE:讀取文件錯(cuò)誤
dns.NOMEM:內(nèi)存溢出
dns.DESTRUCTION:通道以及銷毀
dns.BADSTR:未格式化字符串
dns.BADFLAGS:指定非法標(biāo)記
dns.NONAME:給定的主機(jī)名不是數(shù)字。
dns.BADHINTS:指定非法的提示標(biāo)志。
dns.NOTINITIALIZED:c-ares異步DNS請(qǐng)求庫初始化未完成。
dns.LOADIPHLPAPI:加載iphlpapi.dll(Windows IP輔助API應(yīng)用程序接口模塊)錯(cuò)誤
dns.ADDRGETNETWORKPARAMS:找不到GetNetworkParams(讀取本機(jī)DNS信息)函數(shù)
dns.CANCELLED:DNS查詢?nèi)∠?/p>
dns.lookup() 與 dns.resolve(), dns.resolve*() and dns.reverse()
說明:
在底層,dns.lookup()使用操作系統(tǒng)設(shè)施與大多數(shù)其他程序相同。
例如,dns.lookup()幾乎總是解析給定的主機(jī)名與ping命令一樣。
在許多類POSIX操作系統(tǒng)中, dns.lookup()函數(shù)的行為可以通過改變nsswitch.conf(5)并且/或resolv.conf(5)設(shè)置進(jìn)行改變,
但是需要注意改變這些文件就意味著改變所有正在這個(gè)操作系統(tǒng)中運(yùn)行 的所有進(jìn)程的行為。
盡管以異步JavaScript的角度來調(diào)用dns.lookup(),但在內(nèi)部libuv底層線程池中卻是同步的調(diào)用getaddrinfo(3)
dns.resolve(), dns.resolve*() and dns.reverse()這些功能實(shí)現(xiàn)與dns.lookup()截然不同。
它們不僅沒有使用getaddrinfo(3)并且通過網(wǎng)絡(luò)執(zhí)行DNS查詢。使用異步網(wǎng)絡(luò)通信,并且沒有使用libuv線程池。
因此,這些函數(shù)不會(huì)像使用libuv線程池的dns.lookup()函數(shù)一樣會(huì)對(duì)其它進(jìn)程有負(fù)面影響。
它們不像dns.lookup()一樣使用相同的配置文件。例如,它們不會(huì)使用來自/etc/hosts配置。
希望本文所述對(duì)大家node.js程序設(shè)計(jì)有所幫助。
- Node.js API詳解之 repl模塊用法實(shí)例分析
- Node.js API詳解之 readline模塊用法詳解
- Node.js API詳解之 zlib模塊用法分析
- Node.js API詳解之 net模塊實(shí)例分析
- Node.js API詳解之 Error模塊用法實(shí)例分析
- Node.js API詳解之 console模塊用法詳解
- Node.js API詳解之 util模塊用法實(shí)例分析
- Node.js API詳解之 querystring用法實(shí)例分析
- Node.js API詳解之 string_decoder用法實(shí)例分析
- Node.js API詳解之 tty功能與用法實(shí)例分析
- Node.js API詳解之 assert模塊用法實(shí)例分析
相關(guān)文章
Node.js 進(jìn)程平滑離場(chǎng)剖析小結(jié)
這篇文章主要介紹了Node.js 進(jìn)程平滑離場(chǎng)剖析小結(jié),小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2019-01-01
kafka調(diào)試中遇到Connection to node -1 could not be established. Br
這篇文章主要介紹了kafka調(diào)試中遇到Connection to node -1 could not be established. Broker may not be available的解決方法,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2019-09-09
從零開始學(xué)習(xí)Node.js系列教程六:EventEmitter發(fā)送和接收事件的方法示例
這篇文章主要介紹了Node.js EventEmitter發(fā)送和接收事件的方法,結(jié)合實(shí)例形式分析了EventEmitter發(fā)送和接收事件的原理、實(shí)現(xiàn)方法與相關(guān)操作技巧,需要的朋友可以參考下2017-04-04
node.js中的http.response.addTrailers方法使用說明
這篇文章主要介紹了node.js中的http.response.addTrailers方法使用說明,本文介紹了http.response.addTrailers的方法說明、語法、接收參數(shù)、使用實(shí)例和實(shí)現(xiàn)源碼,需要的朋友可以參考下2014-12-12
NodeJS實(shí)現(xiàn)跨域的方法(使用示例)
CORS是一種 W3C 標(biāo)準(zhǔn),它使用額外的 HTTP 頭來告訴瀏覽器讓運(yùn)行在一個(gè) origin (domain) 上的Web應(yīng)用被準(zhǔn)許訪問來自不同源服務(wù)器上的指定的資源,這篇文章主要介紹了NodeJS實(shí)現(xiàn)跨域的方法,需要的朋友可以參考下2024-05-05

