📜  Node.js DNS 完整参考(1)

📅  最后修改于: 2023-12-03 15:03:12.563000             🧑  作者: Mango

Node.js DNS 完整参考

Node.js 中的 DNS(Domain Name System)模块提供了一些函数用于进行域名解析和反向解析。本文将为程序员们提供完整的参考,帮助大家更好地使用 Node.js 中的 DNS 模块。

DNS 解析

DNS 解析指的是将域名转换为 IP 地址的过程。Node.js 中提供了两个函数用于进行 DNS 解析,分别为 dns.lookup()dns.resolve()

dns.lookup()

dns.lookup() 方法用于进行简单的域名解析:

const dns = require('dns');

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

输出结果:

地址: "93.184.216.34" 地址族: IPv4

如果域名解析失败,则会在 err 参数中返回相应的错误信息。

dns.resolve()

dns.resolve() 方法支持使用不同的查询类型来进行域名解析,例如 A 类型、AAAA 类型和 MX 类型等。对于某个域名,可能会有多个 IP 地址和多个 MX 记录,dns.resolve() 方法可返回一组结果。

const dns = require('dns');

dns.resolve('example.com', 'MX', (err, addresses) => {
  console.log('MX 记录: %j', addresses);
});

输出结果:

MX 记录: [
  {
    "priority": 0,
    "exchange": "mx1.example.com"
  },
  {
    "priority": 10,
    "exchange": "mx2.example.com"
  }
]

如果域名解析失败,则会在 err 参数中返回相应的错误信息。

DNS 反向解析

DNS 反向解析指的是用 IP 地址查询域名的过程。Node.js 中提供了一个函数用于进行 DNS 反向解析,不过需要注意的是,只有 IPv4 地址才能进行反向解析。

dns.reverse()

dns.reverse() 方法用于进行 DNS 反向解析:

const dns = require('dns');

dns.reverse('114.114.114.114', (err, hostnames) => {
  if (err) throw err;

  console.log(`IP 114.114.114.114 对应的域名列表: ${JSON.stringify(hostnames)}`);
});

输出结果:

IP 114.114.114.114 对应的域名列表: ["114dns.com","114dns.net"]

如果反向解析失败,则会在 err 参数中返回相应的错误信息。

DNS 选项

在进行 DNS 查询时,可指定一些选项来控制查询行为。Node.js 中提供了一些常用的 DNS 选项,下面将为大家一一介绍。

选项:ttl

ttl 选项指定 DNS 解析结果的 TTL(Time To Live),即缓存时间。默认情况下,Node.js 会缓存查询结果,下次再进行同样的查询时,不再向 DNS 服务器请求,而是直接从缓存中返回上一次查询的结果。TTL 指定缓存的时间,当 TTL 时间到期时,下次查询将重新向 DNS 服务器请求。

const dns = require('dns');

dns.lookup('example.com', { ttl: true }, (err, address, family) => {
  console.log('地址: %j 地址族: IPv%s', address, family);
});

默认情况下,ttl 选项为 false,表示关闭缓存。

选项:family

family 选项指定返回的 IP 地址族。默认情况下,Node.js 会同时查询 IPv4 和 IPv6 地址,如果想返回指定的地址族,可以设置 family 选项为 46

const dns = require('dns');

dns.lookup('example.com', { family: 4 }, (err, address, family) => {
  console.log('IPv4 地址: %j', address);
});

dns.lookup('example.com', { family: 6 }, (err, address, family) => {
  console.log('IPv6 地址: %j', address);
});

默认情况下,family 选项为 0,表示同时查询 IPv4 和 IPv6 地址。

选项:hints

hints 选项指定协议类型。默认情况下,Node.js 会同时查询 TCP 和 UDP 协议的结果,如果想只查询指定协议的结果,可以设置 hints 选项为 dns.ADDRCONFIGdns.V4MAPPEDdns.ALL

const dns = require('dns');

dns.lookup('example.com', { hints: dns.ADDRCONFIG }, (err, address, family) => {
  console.log('推测协议: %s IPv%s', err ? 'UDP' : 'TCP', family);
});

dns.lookup('example.com', { hints: dns.V4MAPPED }, (err, address1, family1) => {
  console.log('IPv4 地址: %j', address1);

  dns.lookup('example.com', { hints: dns.V4MAPPED | dns.V4MAPPED }, (err, address2, family2) => {
    console.log('IPv4 地址: %j', address2);
  });
});

默认情况下,hints 选项为 dns.ADDRCONFIG,表示同时查询 TCP 和 UDP 协议的结果。

DNS 错误代码

查询 DNS 时,可能会遇到各种错误,下面将为大家介绍一些常见的 DNS 错误代码。

dns.NOTFOUND

表示指定的域名不存在。

const dns = require('dns');

dns.lookup('abc.def.ghij', (err, address, family) => {
  if (err && err.code === 'ENOTFOUND') {
    console.error('域名不存在');
  } else if (err) {
    console.error(err);
  } else {
    console.log('地址: %j 地址族: IPv%s', address, family);
  }
});

输出结果:

域名不存在
dns.FORMERR

表示指定的查询格式有误。

const dns = require('dns');

dns.lookup('example.com', { type: 'x00' }, (err, address, family) => {
  if (err && err.code === 'EFORMERR') {
    console.error('查询格式错误');
  } else if (err) {
    console.error(err);
  } else {
    console.log('地址: %j 地址族: IPv%s', address, family);
  }
});

输出结果:

查询格式错误
dns.SERVFAIL

表示 DNS 服务器返回了无法处理的错误。

const dns = require('dns');

dns.lookup('example.com', { type: 'MX' }, (err, address, family) => {
  if (err && err.code === 'ESERVFAIL') {
    console.error('DNS 服务器返回错误');
  } else if (err) {
    console.error(err);
  } else {
    console.log('地址: %j 地址族: IPv%s', address, family);
  }
});

输出结果:

DNS 服务器返回错误
dns.NOTIMP

表示 DNS 服务器不支持指定的查询类型。

const dns = require('dns');

dns.lookup('example.com', { type: 'SSHFP' }, (err, address, family) => {
  if (err && err.code === 'ENOTIMP') {
    console.error('查询类型不支持');
  } else if (err) {
    console.error(err);
  } else {
    console.log('地址: %j 地址族: IPv%s', address, family);
  }
});

输出结果:

查询类型不支持
dns.REFUSED

表示 DNS 服务器拒绝响应查询请求。

const dns = require('dns');

dns.lookup('example.com', { type: 'SOA' }, (err, address, family) => {
  if (err && err.code === 'EREFUSED') {
    console.error('DNS 服务器拒绝响应');
  } else if (err) {
    console.error(err);
  } else {
    console.log('地址: %j 地址族: IPv%s', address, family);
  }
});

输出结果:

DNS 服务器拒绝响应
总结

本文介绍了 Node.js 中 DNS 模块的相关函数和选项,以及常见的 DNS 错误代码。希望本文能够帮助程序员们更好地使用 Node.js 中的 DNS 模块。