Nodejs的DNS模块包涵有关DNS查询和操作的方法,下面介绍该模块的基本用法以及实现一个DNS查询小工具。

1.获取DNS服务器地址

使用getServers方法,该方法返回一个IP地址组成的数组,如下所示:

const dns = require('dns');
const servers = dns.getServers();
console.log(servers);

返回结果为:

[ '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.使用系统特性域名解析获取IP地址

使用dns.lookup(hostname[, options], callback)方法,options参数包涵以下属性:

  • family:地址协议族,必须为4或6的整数
  • hints:设置getaddrinfo的标志,dns.ADDRCONFIG 或者 dns.V4MAPPED(ipv4映射成ipv6)
  • all:false(默认),布尔值,如设置为true,则返回IP数组,否则返回单个IP地址

callback回调函数有三个参数(err,address,family),如果options的all属性设置为true,则只有(err,addresses)参数且addresses为一个数组,数组元素为{address,family}对象。使用如下所示:

dns.lookup('www.baidu.com',(err,address,family)=>{
if(err) throw err;
console.log('百度网站的IP地址是:'+address+'地址协议族是:IPV'+family);
});

结果如下:

E:\developmentdocument\nodejsdemo>node dns-example.js

百度网站的IP地址是:14.215.177.37地址协议族是:IPV4

设置options的all为true时,结果如下:

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('百度网站的IP地址'+(idx+1)+'是:'+ele.address);
});
});

结果如下:

E:\developmentdocument\nodejsdemo>node dns-example.js

百度网站的IP地址1是:14.215.177.38

百度网站的IP地址2是:14.215.177.37

3.根据IP和端口获取主机名

使用dns.lookupService(address, port, callback)方法,该方法依赖getnameinfo底层函数。

callback函数有三个参数(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对应的主机为:'+hostname+' 协议为:'+service);
});

结果如下:

E:\developmentdocument\nodejsdemo>node dns-example.js

该IP对应的主机为:www.test.zmx.com 协议为:http

4.使用网络域名解析获取IP地址

使用dns.resolve(hostname[, rrtype], callback)方法,rrtype有以下选择:

  • 'A':IPV4,default
  • 'AAAA':IPV6
  • 'MX' - mail exchange records 邮件交换记录
  • 'TXT' - text records 域名配置说明
  • 'SRV' - SRV records 服务器提供的服务
  • 'PTR' - PTR records
  • 'NS' - name server records 域名服务器
  • 'CNAME' - canonical name records 别名记录
  • 'SOA' - start of authority record 起始授权机构
  • 'NAPTR' - name authority pointer record

callback函数有(err, addresses)两个参数,addresses是一个数组,具体成员需要看具体的rrtype,使用如下所示:

//获取IPV4
dns.resolve('www.qq.com','A',(err,address)=>{
if(err) throw err;
console.log(address);//结果为[ '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);//结果为[ '240e:ff:f040:28::a' ]
});
//获取SOA信息
dns.resolve('www.qq.com','SOA',(err,address)=>{
if(err) throw err;
console.log(address);
//结果为
{ 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);//结果为[ 'www.a.shifen.com' ]
});

resovle还存在很多快捷方法,例如:resolve4,resolve6,resolveCname...等等

5.反向域名解析

使用dns.reverse(ip, callback)方法,callback有两个参数(err, hostnames),hostnames是一个域名数组,使用如下所示:

dns.reverse('114.114.114.114',(err,hostnames)=>{
if(err) throw err;
console.log(hostnames);//结果为[ 'public1.114dns.com' ]
});

学完了以上的知识后,可以做个DNS查询的小工具,如下所示:

第一步,写个HTML静态页面,如下:

<!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="请输入域名">
</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 />') : '没有查询到结果';
}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>

接着编写服务端代码,如下:

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');

运行效果如下:



到此这个小工具便完成了。

Node.js:DNS模块的使用的更多相关文章

  1. Node.js DNS 模块

    Node.js DNS 模块用于解析域名.引入 DNS 模块语法格式如下: var dns = require("dns") 方法 序号 方法 & 描述 1 dns.loo ...

  2. [Node.js]DNS模块

    摘要 nds模块是node.js用于解析域名的模块,对域名的解析非常快捷方便. DNS 引入dns模块 //引入dns模块 var dns=require("dns"); 方法 序 ...

  3. Node.js工具模块

    在Node.js的模块库中提供实用的模块数量. 这些模块都是很常见的,并同时开发基于任何节点的应用程序频繁使用. S.N. 模块的名称和说明 1 OS Module提供基本的操作系统相关的实用功能 2 ...

  4. Node.js的模块载入方式与机制

    Node.js中模块可以通过文件路径或名字获取模块的引用.模块的引用会映射到一个js文件路径,除非它是一个Node内置模块.Node的内置模块公开了一些常用的API给开发者,并且它们在Node进程开始 ...

  5. Node.js Web模块

    什么是Web服务器? Web服务器是处理由HTTP客户端发送的,如web浏览器的HTTP请求的软件应用程序,并返回响应于客户端网页. Web服务器通常伴随着图片,样式表和脚本的HTML文档. 大多数W ...

  6. node.js基础模块http、网页分析工具cherrio实现爬虫

    node.js基础模块http.网页分析工具cherrio实现爬虫 一.前言      说是爬虫初探,其实并没有用到爬虫相关第三方类库,主要用了node.js基础模块http.网页分析工具cherri ...

  7. Node.js:模块

    概要:本篇博客主要介绍node.js的模块 1.创建模块 在node.js中创建一个模块非常简单,因为一个文件就是一个模块.我们只需要明白如何从其他文件中获取这个模块.Node.js提供了 expor ...

  8. node.js之模块

    node.js之模块 1.自定义模块的设置 加载自定义模块利用require: eg: require('./custom_module.js') 2.从模块外部访问模块内的成员 2.1使用expor ...

  9. Node.js的安装以及Node.js的模块管理

    索引: Node.js的安装以及Node.js的模块管理Node.js开发环境搭建以及对ES6的支持Node.js构建Vue.js项目Vue.js单文件组件的开发基于Vue.js的UI组件(Eleme ...

  10. Node.js Net 模块

    Node.js Net 模块提供了一些用于底层的网络通信的小工具,包含了创建服务器/客户端的方法,我们可以通过以下方式引入该模块: var net = require("net") ...

随机推荐

  1. H5坦克大战之【建造敌人的坦克】

      公司这几天在准备新版本的上线,今天才忙里偷闲来写这篇博客.接着上一篇的"H5坦克大战之[玩家控制坦克移动2]"(http://www.cnblogs.com/zhouhuan/ ...

  2. 菜鸟学Struts2——Results

    在对Struts2的Action学习之后,对Struts2的Result进行学习.主要对Struts2文档Guides中的Results分支进行学习,如下图: 1.Result Types(Resul ...

  3. 调用AJAX做登陆和注册

    先建立一个页面来检测一下我们建立的用户名能不能用,看一下有没有已经存在的用户名吗 可以通过ajax提示一下 $("#uid").blur(function(){ //取用户名 va ...

  4. Vue.js 2.0 和 React、Augular等其他框架的全方位对比

    引言 这个页面无疑是最难编写的,但也是非常重要的.或许你遇到了一些问题并且先前用其他的框架解决了.来这里的目的是看看Vue是否有更好的解决方案.那么你就来对了. 客观来说,作为核心团队成员,显然我们会 ...

  5. WebApi - 路由

    这段时间的博客打算和大家一起分享下webapi的使用和心得,主要原因是群里面有朋友说希望能有这方面的文章分享,随便自己也再回顾下:后面将会和大家分不同篇章来分享交流心得,希望各位多多扫码支持和点赞,谢 ...

  6. angular2系列教程(九)Jsonp、URLSearchParams、中断选择数据流

    大家好,今天我们要讲的是http模块的第二部分,主要学习ng2中Jsonp.URLSearchParams.observable中断选择数据流的用法. 例子

  7. HTML学习笔记

    HTML学习笔记 2016年12月15日整理 Chapter1 URL(scheme://host.domain:port/path/filename) scheme: 定义因特网服务的类型,常见的为 ...

  8. win7下利用ftp实现华为路由器的上传和下载

    win7下利用ftp实现华为路由器的上传和下载 1.  Win7下ftp的安装和配置 (1)开始->控制面板->程序->程序和功能->打开或关闭Windows功能 (2)在Wi ...

  9. Android中的沉浸式状态栏效果

    无意间了解到沉浸式状态栏,感觉贼拉的高大上,于是就是试着去了解一下,就有了这篇文章.下面就来了解一下啥叫沉浸式状态栏.传统的手机状态栏是呈现出黑色条状的,有的和手机主界面有很明显的区别.这一样就在一定 ...

  10. linux练习题

    观察系统当前进程的运行情况的命令是( ):A.freeB.dmesgC.topD.last 答案:http://hovertree.com/tiku/bjag/foxg5n0q.htm Linux系统 ...