Search code examples
node.jsaxiosdns

How to set DNS server for a single axios get request?


I know I can set the DNS servers in node

dns.setServers([
   '4.4.4.4',
   '[2001:4860:4860::8888]',
]);

But this is set globally and I'm developing a module (dependency) and I don't want to affect the main program (dependent) DNS server

Can I set specific DNS servers only for a single axios request?

const axios = require('axios');

axios.get('https://example.org')
  .then(response => {
    console.log(response.data); // Logs the data returned
  })
  .catch(error => {
    console.error(error.message); // Logs any error that occurs
  });

I checked the request configs for axios and found nothing.


Solution

  • Found the solution

    Solution 1

    Using the suggestion from @Barmar on the comments, store old DNS servers in a variable and restore them again right after the axios request

    const dns = require('dns')
    const axios = require('axios')
    
    const oldDnsServers = dns.getServers()
    
    // set new servers
    dns.setServers([
       '4.4.4.4',
       '[2001:4860:4860::8888]'
    ])
    
    axios.get('https://example.org')
      .then(response => {
        console.log(response.data) // Logs the data returned
      })
      .catch(error => {
        console.error(error.message) // Logs any error that occurs
      })
    
    dns.setServers(oldDnsServers)
    

    Solution 2

    A more elegant solution is to use the lookup function and dns.Resolver class

    const axios = require('axios')
    const dns = require('dns')
    
    const resolver = new dns.Resolver()
    resolver.setServers([
       '4.4.4.4',
       '[2001:4860:4860::8888]'
    ])
    
    const customLookup = (hostname, options, callback) => {
      // Resolve both IPv4 and IPv6 addresses
      if (options.family === 6) {
        resolver.resolve6(hostname, (err, addresses) => {
          if (err) return callback(err)
          callback(null, addresses[0], 6)
        })
      } else {
        resolver.resolve4(hostname, (err, addresses) => {
          if (err) return callback(err)
          callback(null, addresses[0], 4)
        })
      }
    }
    
    axios.get('https://example.org', { lookup: customLookup })
      .then(response => {
        console.log(response.data); // Logs the data returned
      })
      .catch(error => {
        console.error(error.message); // Logs any error that occurs
      })