使用dns.lookup()在node.js中通过域名获取IP地址。

17

参考这份文档,我在console.log中获取域名的IP地址,代码如下:

const dns = require('dns');

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

console.log的输出结果很好。但是我无法在该范围之外获取地址,dns.lookup函数的返回语句是一个对象。

我到目前为止尝试过的:

const ipAddress = dns.lookup("www.aWebSiteName.am", (err, address, family) => {
  if(err) throw err;
  return address;
});

console.log(ipAddress);

我得到的是:

GetAddrInfoReqWrap {
  callback: [Function],
  family: 0,
  hostname: 'www.aWebSiteName.am',
  oncomplete: [Function: onlookup] }
5个回答

23

由于dns.lookup()函数是异步的,因此您无法这样做。

尽管从JavaScript的角度来看,对dns.lookup()的调用将是异步的,但它实际上是在libuv线程池中运行的同步调用getaddrinfo(3)。 这可能会对某些应用程序产生令人惊讶的负面性能影响,请参阅UV_THREADPOOL_SIZE文档以了解更多信息。

有不同的方法来获取结果。欢迎来到JS世界!

回调函数

dns.lookup("www.aWebSiteName.am", (err, address, family) => {
  if(err) throw err;
  printResult(address);
});

function printResult(address) {
   console.log(address);
}

承诺

const lookupPromise = new Promise((resolve, reject) => {
    dns.lookup("www.aWebSiteName.am", (err, address, family) => {
        if(err) reject(err);
        resolve(address);
    });
});

lookupPromise().then(res => console.log(res)).catch(err => console.error(err));

Promise异步/等待

async function lookupPromise() {
    return new Promise((resolve, reject) => {
        dns.lookup("www.aWebSiteName.am", (err, address, family) => {
            if(err) reject(err);
            resolve(address);
        });
   });
};

try {
    const address = await lookupPromise();
} catch(err) {
    console.error(err);
}

6

这是正常的,因为"dns.lookup"是异步执行的。

所以你不能仅仅使用函数返回的值。

你需要在回调函数中处理逻辑或者编写一个帮助函数将其转换成promise,并在async函数中使用await执行。

像下面这样:

function lookup(domain) {
  return new Promise((resolve, reject) => {
    dns.lookup(address, (err, address, family) => {
      if (err) {
        reject(err)
      } else {
        resolve({ address, family })
      }
    })
  })
}

async function test() {
  let ipAddress = await lookup(("www.aWebSiteName.am");
}

编辑:

你也可以使用以下方法:

const dns = require('dns');
dnsPromises = dns.promises;

async function test() {
  let data = await dnsPromises.lookup(("www.aWebSiteName.am");
}

0

虽然这是一个老问题,但我想发表我的观点。

在寻找dns.lookup()函数示例时,我总是发现它们在.lookup方法内部报告一些console.log()输出。

但我正在寻找一个简单的true/false响应值。 类似于:我有这个URL,请检查它是否在互联网上。

最初,我的解决方案返回了一个true/false。我将其调整为返回地址,正如您在问题中所要求的那样。

因此,这是我的个人实现。

async function getAddr(href) {
  console.log("Check =>", href);
  let resVal = undefined;
  await dns.lookup( new URL(href).host , (err, address, family) => {
    return resVal = (err) ? false : address;
  });

  await new Promise((resolve, reject) => setTimeout(resolve, 1000));
  console.log("Check =>", href, "is host Good? [", resVal, "]");
  return resVal;
}

我认为这是管理个性化答案最简单的方式。无论您的需求如何,都可以立即调整和个性化。

我保留了console.log()语句,只是为了快速测试脚本。


0
DNS查询是异步进行的,当回调函数触发时可以设置其值。只有在回调函数中得到地址才能继续执行。将一个变量放在周围并不会等待回调函数的触发,因此该变量不可用。
dns.lookup("www.aWebSiteName.am", (err, address, family) => {
  if(err) throw err;
   // Here you have access to the variable address
   // Execute code or call function which needs the address here
});


0
NodeJS已经有一个带有promises的版本。
在一个lambda函数内部:
import { promises as dnsPromises } from 'dns';
 
export const handler = async(event) => {
    return await dnsPromises.lookup('foo.bar.example.com');
};

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接