您好,登錄后才能下訂單哦!
這篇文章主要講解了Node.js API中如何使用dns模塊,內容清晰明了,對此有興趣的小伙伴可以學習一下,相信大家閱讀完之后會有幫助。
Node.js API詳解之 dns
dns (域名服務器)模塊包含兩類函數:
第一類函數,使用底層操作系統工具進行域名解析,且無需進行網絡通信。 這類函數只有一個: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
第二類函數,連接到一個真實的 DNS 服務器進行域名解析,且始終使用網絡進行 DNS 查詢。
這類函數包含了 dns 模塊中除 dns.lookup() 以外的所有函數。
這些函數使用與 dns.lookup() 不同的配置文件(例如 /etc/hosts)。
這類函數適合于那些不想使用底層操作系統工具進行域名解析、而是想使用網絡進行 DNS 查詢的開發者。
例子,解析 ‘archive.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"]
說明:
返回一個用于當前DNF解析的IP地址的數組的字符串,格式根據rfc5952。
如果使用自定義端口,那么字符串將包括一個端口部分。
demo:
const dns= require('dns'); console.log( dns.getServers() ); // [ '172.116.20.254', '127.0.0.1' ]
說明:
設置IP地址服務器端口在進行DNS解析時可用,servers參數是一個rfc5952數組格式的地址。
如果端口是IANA默認端口(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' ]
說明:
解析hostname(例如:'nodejs.org')第一個找到的A(IPv4)或AAAA(IPv6)記錄。
options可以是對象或者整數。如果options沒有被提供,那么IPv4 和 IPv6都是有效的。如果options是整數,只能是4或6。
另外,options可以是一個含有以下屬性的對象:
family: T地址族。如果提供,必須為整數4或6。如果沒有提供,只接受IPv4和IPv6地址。
all:值為true時, 回調函數返回一個包含所有解析后地址的數組,否則只返回一個地址。默認值為false
hints:如果提供,它必須是一個或多個支持的getaddrinfo標識。如果沒有提供,那么沒有標識被傳遞給getaddrinfo。
多個標識可以通過在邏輯上ORing它們的值,來傳遞給hints。支持的getaddrinfo標識:
dns.ADDRCONFIG: 返回當前系統支持的地址類型。例如,如果當前系統至少配置了一個 IPv4 地址,則返回 IPv4地址。不考慮回環地址。
dns.V4MAPPED: 如果指定了 IPv6 家族, 但是沒有找到 IPv6 地址,將返回 IPv4 映射的 IPv6地址。在有些操作系統中不支持(e.g FreeBSD 10.1)。
回調函數包含(err, address, family)參數。
address是IPv4或IPv6地址字符串。
family、是整數4或6,表示地址族(不一定是最初傳遞給查找的值)。
當all屬性被設置為true時,回調函數參數變為(err, addresses),addresses則變成一個由address 和 family 屬性組成的對象數組。
dns.lookup() 不需要與DNS協議有任何關系。它僅僅是一個連接名字和地址的操作系統功能。
在任何的node.js程序中,它的實現對表現有一些微妙但是重要的影響。
盡管dns.lookup()和各種dns.resolve *()/ dns.reverse()函數有相同的目標將網絡的名字與網絡地址聯系在一起(反之亦然),
他們的行為是完全不同的。 這些差異可以有微妙但重大影響著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}]
說明:
將參數address和port傳入操作系統底層getnameinfo服務來解析處理并返回主機名。
如果address不是有效的IP地址,會拋出TypeError。port必須是一個整數.如果不是規定的端口號,會拋出TypeError.
出錯情況下,err是一個Error對象,err.code代碼錯誤碼。
demo:
const dns = require('dns'); dns.lookupService('127.0.0.1', 22, (err, hostname, service) => { console.log(hostname, service); // localhost ssh });
說明:
執行一個反向DNS查詢返回IPv4或IPv6地址的主機名的數組。
demo:
const dns = require('dns'); dns.reverse('101.20.17.16', (err, hostname) => { console.log(hostname); });
說明:
DNS請求的獨立解析程序。
使用默認的設置創建一個新的解析程序。
為一個解析程序設置servers使用resolver.setServers(),它不會影響其他的解析程序:
demo:
const { Resolver } = require('dns'); const resolver = new Resolver(); resolver.setServers(['4.4.4.4']); resolver.resolve4('baidu.com', (err, addresses) => { console.log(addresses); });
說明:
取消這個解析程序的未解決的DNS查詢,相應的回調用一個ECANCELLED碼調用。
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();
說明:
hostname:解析的主機名。
rrtype:資源記錄類型. 默認: ‘A'.c
使用DNS協議來解析一個主機名(e.g. ‘nodejs.org')為一個資源記錄的數組。
回調函數的參數為(err, records)。當成功時,records將是一個資源記錄的數組。它的類型和結構取決于rrtype。
下面是不同rrtype對應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協議解析IPv4地址主機名(A記錄)。
adresses參數是傳遞給callback函數的IPv4地址數組。(例如:[‘74.125.79.104', ‘74.125.79.105', ‘74.125.79.106'])
hostname:需要解析的主機名
options.ttl:記錄每一條記錄的存活次數 (TTL)。如果為 true, 返回的結果將會為 Object 的數組,就像 { address: ‘1.2.3.4', ttl: 60 } 帶有 TTL 秒數的記錄,而不是 string 的數組.
demo:
const dns = require('dns'); dns.resolve4('archive.org', {ttl: true}, (err, addresses) => { if (err) throw err; console.log(`IPv4地址數組: ${JSON.stringify(addresses)}`); }); // IPv4地址數組: [{"address":"207.241.224.2","ttl":58}]
說明:
使用DNS協議解析IPv6地址主機名(AAAA記錄)。
adresses參數是傳遞給callback函數的IPv6地址數組.
demo:
const dns = require('dns'); dns.resolve6('www.taobao.com', {ttl: true}, (err, addresses) => { if (err) throw err; console.log(`IPv6地址主機名: ${JSON.stringify(addresses)}`); }); // IPv6地址主機名: []
說明:
使用DNS協議解析CNAME記錄主機名。
adresses參數是傳遞給callback函數規范內有效的主機名數組(例如:[‘bar.example.com']).
demo:
const dns = require('dns'); dns.resolveCname('www.taobao.com', (err, addresses) => { if (err) throw err; console.log(`CNAME記錄主機名: ${JSON.stringify(addresses)}`); }); // CNAME記錄主機名: ["www.taobao.com.danuoyi.tbcache.com"]
說明:
使用DNS協議處理郵件交換記錄主機名(MX記錄)。
adresses參數是傳遞給callback函數的主機名對象數組,對
象包含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協議來處理基于正則表達式匹配的記錄(NAPTR記錄)的主機名。
adresses參數是傳遞給callback函數的主機名對象數組,對象包含屬性:
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協議處理名稱服務器主機名記錄(NS記錄)。
adresses為有效的名稱服務器記錄主機名數組(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協議處理主機名引用記錄(PTR記錄)。
addresses參數將一個字符串數組傳遞給回調函數callback,其中包含回復記錄。
demo:
const dns = require('dns'); dns.resolvePtr('www.taobao.com', (err, addresses) => { if (err) throw err; console.log(`PTR記錄: ${JSON.stringify(addresses)}`); });
說明:
使用DNS協議處理主機名子域名記錄(SOA記錄)。addresses參數為一個對象包含以下屬性:
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協議來處理主機名服務記錄(SRV記錄)。
callback函數返回的addresses參數為對象數組,每個對象包含以下屬性:
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協議處理文本查詢主機名(TXT記錄)。回調函數callback會返回records參數,
它是一個文本記錄與主機名一一對應的二維數組(例如:[ [‘v=spf1 ip4:0.0.0.0 ‘, ‘~all' ] ]).
每個數組文本塊包含一條記錄。根據用例,這些可以是連接在一起或單獨對待。
demo:
const dns = require('dns'); dns.resolveTxt('www.taobao.com', (err, addresses) => { if (err) throw err; console.log(`TXT記錄: ${JSON.stringify(addresses)}`); });
說明:
使用DNS協議解析所有記錄。
callback函數的參數將是一個包含各種類型記錄的數組。每個對象都有一個屬性type,指示當前記錄的類型。
“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 } ]
說明:
每個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請求庫初始化未完成。
dns.LOADIPHLPAPI:加載iphlpapi.dll(Windows IP輔助API應用程序接口模塊)錯誤
dns.ADDRGETNETWORKPARAMS:找不到GetNetworkParams(讀取本機DNS信息)函數
dns.CANCELLED:DNS查詢取消
說明:
在底層,dns.lookup()使用操作系統設施與大多數其他程序相同。
例如,dns.lookup()幾乎總是解析給定的主機名與ping命令一樣。
在許多類POSIX操作系統中, dns.lookup()函數的行為可以通過改變nsswitch.conf(5)并且/或resolv.conf(5)設置進行改變,
但是需要注意改變這些文件就意味著改變所有正在這個操作系統中運行 的所有進程的行為。
盡管以異步JavaScript的角度來調用dns.lookup(),但在內部libuv底層線程池中卻是同步的調用getaddrinfo(3)
dns.resolve(), dns.resolve*() and dns.reverse()這些功能實現與dns.lookup()截然不同。
它們不僅沒有使用getaddrinfo(3)并且通過網絡執行DNS查詢。使用異步網絡通信,并且沒有使用libuv線程池。
因此,這些函數不會像使用libuv線程池的dns.lookup()函數一樣會對其它進程有負面影響。
它們不像dns.lookup()一樣使用相同的配置文件。例如,它們不會使用來自/etc/hosts配置。
看完上述內容,是不是對Node.js API中如何使用dns模塊有進一步的了解,如果還想學習更多內容,歡迎關注億速云行業資訊頻道。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。