淺析Node.js:DNS模塊的使用
Nodejs的DNS模塊包涵有關(guān)DNS查詢和操作的方法,下面介紹該模塊的基本用法以及實(shí)現(xiàn)一個(gè)DNS查詢小工具。
1.獲取DNS服務(wù)器地址
使用getServers
方法,該方法返回一個(gè)IP地址組成的數(shù)組,如下所示:
const dns = require('dns'); const servers = dns.getServers(); console.log(servers);
返回結(jié)果為:
[ '114.114.114.114', '8.8.8.8',
'fec0:0:0:ffff::1', '114.114.114.114',
'8.8.8.8', '114.114.114.114',
'8.8.8.8' ]
2.使用系統(tǒng)特性域名解析獲取IP地址
使用dns.lookup(hostname[, options], callback)
方法,options參數(shù)包涵以下屬性:
- family:地址協(xié)議族,必須為4或6的整數(shù)
- hints:設(shè)置getaddrinfo的標(biāo)志,dns.ADDRCONFIG 或者 dns.V4MAPPED(ipv4映射成ipv6)
- all:false(默認(rèn)),布爾值,如設(shè)置為true,則返回IP數(shù)組,否則返回單個(gè)IP地址
callback回調(diào)函數(shù)有三個(gè)參數(shù)(err,address,family),如果options的all屬性設(shè)置為true,則只有(err,addresses)參數(shù)且addresses為一個(gè)數(shù)組,數(shù)組元素為{address,family}對(duì)象。使用如下所示:
dns.lookup('www.baidu.com',(err,address,family)=>{ if(err) throw err; console.log('百度網(wǎng)站的IP地址是:'+address+'地址協(xié)議族是:IPV'+family); });
結(jié)果如下:
E:\developmentdocument\nodejsdemo>node dns-example.js
百度網(wǎng)站的IP地址是:14.215.177.37地址協(xié)議族是:IPV4
設(shè)置options的all為true時(shí),結(jié)果如下:
dns.lookup('www.baidu.com',{family:4,all:!0,hints:dns.ADDRCONFIG|dns.V4MAPPED},(err,addresses)=>{ if(err) throw err; addresses.forEach((ele,idx,arr)=>{ console.log('百度網(wǎng)站的IP地址'+(idx+1)+'是:'+ele.address); }); });
結(jié)果如下:
E:\developmentdocument\nodejsdemo>node dns-example.js
百度網(wǎng)站的IP地址1是:14.215.177.38
百度網(wǎng)站的IP地址2是:14.215.177.37
3.根據(jù)IP和端口獲取主機(jī)名
使用dns.lookupService(address, port, callback)
方法,該方法依賴getnameinfo底層函數(shù)。
callback函數(shù)有三個(gè)參數(shù)(err, hostname, service),service是protocol,為http或https,使用如下所示:
dns.lookupService('127.0.0.1',80,(err,hostname,service)=>{ if(err) console.log(err); console.log('該IP對(duì)應(yīng)的主機(jī)為:'+hostname+' 協(xié)議為:'+service); });
結(jié)果如下:
E:\developmentdocument\nodejsdemo>node dns-example.js
該IP對(duì)應(yīng)的主機(jī)為:www.test.zmx.com 協(xié)議為:http
4.使用網(wǎng)絡(luò)域名解析獲取IP地址
使用dns.resolve(hostname[, rrtype], callback)
方法,rrtype有以下選擇:
- 'A':IPV4,default
- 'AAAA':IPV6
- 'MX' - mail exchange records 郵件交換記錄
- 'TXT' - text records 域名配置說明
- 'SRV' - SRV records 服務(wù)器提供的服務(wù)
- 'PTR' - PTR records
- 'NS' - name server records 域名服務(wù)器
- 'CNAME' - canonical name records 別名記錄
- 'SOA' - start of authority record 起始授權(quán)機(jī)構(gòu)
- 'NAPTR' - name authority pointer record
callback函數(shù)有(err, addresses)兩個(gè)參數(shù),addresses是一個(gè)數(shù)組,具體成員需要看具體的rrtype,使用如下所示:
//獲取IPV4 dns.resolve('www.qq.com','A',(err,address)=>{ if(err) throw err; console.log(address);//結(jié)果為[ '14.17.32.211', '14.17.42.40', '59.37.96.63' ] }); //獲取IPV6 dns.resolve('www.qq.com','AAAA',(err,address)=>{ if(err) throw err; console.log(address);//結(jié)果為[ '240e:ff:f040:28::a' ] }); //獲取SOA信息 dns.resolve('www.qq.com','SOA',(err,address)=>{ if(err) throw err; console.log(address); //結(jié)果為 { nsname: 'ns-tel1.qq.com', hostmaster: 'webmaster.qq.com', serial: 1380440321, refresh: 300, retry: 600, expire: 86400, minttl: 300 } }); //獲取別名CNAME dns.resolve('www.baidu.com','CNAME',(err,address)=>{ if(err) throw err; console.log(address);//結(jié)果為[ 'www.a.shifen.com' ] });
resovle還存在很多快捷方法,例如:resolve4,resolve6,resolveCname...等等
5.反向域名解析
使用dns.reverse(ip, callback)
方法,callback有兩個(gè)參數(shù)(err, hostnames),hostnames是一個(gè)域名數(shù)組,使用如下所示:
dns.reverse('114.114.114.114',(err,hostnames)=>{ if(err) throw err; console.log(hostnames);//結(jié)果為[ 'public1.114dns.com' ] });
學(xué)完了以上的知識(shí)后,可以做個(gè)DNS查詢的小工具,如下所示:
第一步,寫個(gè)HTML靜態(tài)頁面,如下:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>DNS查詢工具</title> <style type="text/css"> html,body{ width: 100%; height: 100%; } body{ display: flex; align-items: center; justify-content: center; flex-direction: column; } *{ margin:0; padding: 0; } ul{ list-style: none; } .res{line-height: 24px; color:#333; } .clearfix:after{ display: block; content:''; height: 0; visibility: hidden; clear: both;} .fl{ float:left; } .g-wrap{ display: flex; width:560px; height: 40px; } .u-list{position: relative; flex:1; } .u-inp{flex:3; border:1px solid #ccc; border-left: none; border-right:none; padding:11px 0 11px 10px;} .u-btn{ flex:1; } .list{ display: none; position: absolute; left: 0px; top:40px; width: 100%; border:1px solid #ccc; border-top:none; border-bottom:none; box-sizing: content-box; } .item{ height: 30px; line-height: 30px; text-align: center; color: #666; border-bottom: 1px solid #ccc; cursor:pointer;} .item:hover{ color:#0087dc; } .u-list .type{ display: block; width: 100%; line-height: 38px; border:1px solid #ccc; text-align: center; color:#666; text-decoration: none; } .u-list .type:after{ content: ''; position: absolute; width:0; height:0; border:8px solid transparent; border-top-color:#ccc; right:4px; top:16px;} .u-inp input{ width: 100%; border:none; outline: none; height: 18px; line-height: 18px; color:#666; vertical-align: top; font-size: 14px; } .u-btn .btn{ display: block; line-height: 40px; text-align: center; background-color: #0087dc; color:#fff; font-size: 16px; cursor:pointer; transition: background-color .3s;} .u-btn .btn:hover{ background-color: #0060b2; } </style> </head> <body> <div id="res" class="res"></div> <div class="g-wrap clearfix"> <div class="u-list fl"> <a href="javascript:;" class="type" id="type" data-value="A">IPV4</a> <ul id="list" class="list"> <li class="item" data-value="A">IPV4</li> <li class="item" data-value="AAAA">IPV6</li> <li class="item" data-value="CNAME">CNAME</li> <li class="item" data-value="SOA">SOA</li> </ul> </div> <div class="u-inp fl"> <input type="text" class="host" id="host" placeholder="請(qǐng)輸入域名"> </div> <div class="u-btn fl"> <span class="btn" id="btn">查詢</span> </div> </div> <script> function hide(el){ el.style.display = 'none'; } function show(el){ el.style.display = 'block'; } function dealResult(responseText){ var ips = [], result = ''; ips = JSON.parse(responseText).ips; if(Array.isArray(ips)){ result = ips.length > 0 ? ips.join('<br />') : '沒有查詢到結(jié)果'; }else if({}.toString.call(ips) === '[object Object]'){ result = JSON.stringify(ips); } res.innerHTML = result; } type.addEventListener('click',function(e){ e.stopPropagation(); show(list); },!1); [].slice.call(document.body.querySelectorAll('.item')).forEach(function(el,idx,arr){ el.addEventListener('click',function(e){ type.innerText = this.innerText; type.dataset.value = this.dataset.value; },!1); }); document.body.addEventListener('click',function(e){ if(list.style.display === 'block'){ hide(list); } },!1); btn.addEventListener('click',function(e){ var hostname = host.value.trim(), rrtype = type.dataset.value.toUpperCase(); if(hostname == '') return; if(hostname.indexOf('http://') === 0) hostname = hostname.replace('http://',''); var xhr = new XMLHttpRequest(), method = "POST", url = "/dnslookup"; xhr.open(method, url, true); xhr.onreadystatechange = function() { if (xhr.readyState === XMLHttpRequest.DONE && xhr.status === 200) { dealResult(xhr.responseText); } }; xhr.setRequestHeader("Content-Type","application/x-www-form-urlencoded"); xhr.send('host='+hostname+'&rrtype='+rrtype); },!1); </script> </body> </html>
接著編寫服務(wù)端代碼,如下:
var http = require('http'), url = require('url'), dns = require('dns'), qs = require('querystring'), fs = require('fs'); function router(req,res,pathname){ switch(pathname){ case '/dnslookup': lookup(req,res); break; default: showIndex(req,res); } } function showIndex(req,res){ var pagePath = __dirname+'/'+'dns-lookup.html'; var html = fs.readFileSync(pagePath); res.end(html); } function lookup(req,res){ var postData = ''; req.on('data',function(data){ postData+=data; }); req.on('end',function(data){ var json = qs.parse(postData); var hostname = json.host; var rrtype = json.rrtype; dns.resolve(hostname,rrtype,function(err,adresses){ if(err){ res.end(JSON.stringify({errcode:1,ips:[]})); } res.end(JSON.stringify({errcode:0,ips:adresses})); }); }); } http.createServer(function(req,res){ var pathname = url.parse(req.url).pathname; req.setEncoding("utf8"); res.writeHead(200,{'Content-Type':'text/html'}); router(req,res,pathname); }).listen(3000,'127.0.0.1');
運(yùn)行效果如下:
到此這個(gè)小工具便完成了。
以上就是本文的全部內(nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- 詳解從買域名到使用pm2部署node.js項(xiàng)目全過程
- Node.js設(shè)置CORS跨域請(qǐng)求中多域名白名單的方法
- Nodejs下DNS緩存問題淺析
- node.js中的dns.getServers方法使用說明
- Node.js中DNS模塊學(xué)習(xí)總結(jié)
- 150行Node.js實(shí)現(xiàn)的dns代理工具
- 獲取本機(jī)IP地址的實(shí)例(JavaScript / Node.js)
- nodejs獲取本機(jī)內(nèi)網(wǎng)和外網(wǎng)ip地址的實(shí)現(xiàn)代碼
- node.js域名解析實(shí)現(xiàn)方法詳解
相關(guān)文章
Node.js+Express+Vue+MySQL+axios的項(xiàng)目搭建全過程
這篇文章主要介紹了Node.js+Express+Vue+MySQL+axios的項(xiàng)目搭建全過程,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-12-12Node.js基礎(chǔ)入門之模塊與npm包管理器使用詳解
Node.js是一個(gè)基于Chrome?V8引擎的JavaScript運(yùn)行時(shí)。類似于Java中的JRE,.Net中的CLR。本文將詳細(xì)為大家介紹Node.js中的模塊與npm包管理器的使用,需要的可以參考一下2022-03-03詳解Node.js使用token進(jìn)行認(rèn)證的簡單示例
這篇文章主要介紹了詳解Node.js使用token進(jìn)行認(rèn)證的簡單示例,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-05-05