nodejs的DNS模块浅析

China☆狼群 提交于 2019-11-27 12:13:11

node.js的DNS模块包含两类函数:

一、 第一类函数,使用底层操作系统工具进行域名解析,且无需进行网络通信。 这类函数只有一个:dns.lookup()。 
eg:

const dns = require('dns');

dns.lookup('iana.org', (err, address, family) => {
  console.log('IP 地址: %j 地址族: IPv%s', address, family);
});

输出: IP 地址: “192.0.43.8” 地址族: IPv4

二、 第二类函数,连接到一个真实的 DNS 服务器进行域名解析,且始终使用网络进行 DNS 查询。 这类函数包含了 dns 模块中除 dns.lookup() 以外的所有函数。 这些函数使用与 dns.lookup() 不同的配置文件(例如 /etc/hosts)。 这类函数适合于那些不想使用底层操作系统工具进行域名解析、而是想使用网络进行 DNS 查询的开发者。

2.1根据IP和端口获取主机名:dns.lookupService(address, port, callback)
 

const dns = require('dns');

dns.lookupService('127.0.0.1',80,(err,hostname,service)=>{
    if(err) console.log(err);
    console.log('该IP对应的主机为:'+hostname+' 协议为:'+service);
});

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

2.2使用网络域名解析获取IP地址:dns.resolve(hostname[, rrtype], callback) 
hostname是域名,rrtype有以下选择: 

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,resolveMx,resolveNaptr…等等

2.3反向域名解析:dns.reverse(ip,callback)

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

综上,可以做个DNS查询的小工具,第一步,新建静态页面dns-lookup.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; margin-top: 30px;}
        .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; }
        .main{
            margin: 0 auto;
            width: 600px;
            height: 250px;
            background-color: #f7f7f7f7;
            border-radius:10px;
        }
        h2{text-align: center;
            height: 60px;
            line-height: 60px;
            background-color:#e7e7e7;
            border-radius:10px 10px 0px 0px;}
        .res{
            margin-bottom: 0px;
            background-color: #e7e7e7;
            width: 600px;
            height: 60px;
            margin-top: 60px;
            border-radius: 0px 0px 10px 10px;
            text-align: center;
            line-height: 30px;

        }
    </style>
</head>
<body>
    <div class="main">
        <h2>DNS查询小工具</h2>
        <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" style="background-color:#f7f7f7f7; " class="host" id="host" placeholder="请输入域名">
            </div>
            <div class="u-btn fl">
                <span class="btn" id="btn">查询</span>
            </div>
        </div>
        <div id="res" class="res"></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>

第二步编写服务端代码,新建dnslookup.js,如下:

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 dnslookup.js 

效果图 :

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!