NodeJS,绕过linux主机文件

时间:2017-06-02 18:17:46

标签: node.js hosts

NodeJS中有没有办法绕过linux的/ etc / hosts文件?

例如,如果我在hosts文件中有一个条目,例如: 127.0.0.1 example.com

我如何从NodeJS访问'real'example.com?

我不想暂时修改/ etc / hosts来执行此操作,因为它可能会带来一些问题并且不是一个干净的解决方案。

提前致谢!

2 个答案:

答案 0 :(得分:3)

我一开始并没有想到可能,但后来偶然发现了ignore the hosts file on Linux的方法。另外,我发现Node中内置了DNS API。基本上,默认情况下,Node会按照操作系统进行DNS查找(从/etc/hosts读取,如果不必,则不进行DNS查询)。但是,Node还公开了一种通过显式发出DNS请求来解析主机名的方法。这将为您提供您正在寻找的IP地址。

$ cat /etc/hosts
<snip>
127.0.0.1 google.com
$ ping google.com
PING google.com (127.0.0.1) 56(84) bytes of data.
...

这表明主机文件肯定有效。

const dns = require('dns')

// This will use the hosts file.
dns.lookup('google.com', function (err, res) {
  console.log('This computer thinks Google is located at: ' + res)
})

dns.resolve4('google.com', function (err, res) {
  console.log('A real IP address of Google is: ' + res[0])
})

按预期输出不同的值:

$ node host.js
This computer thinks Google is located at: 127.0.0.1
A real IP address of Google is: 69.77.145.253

请注意,我使用最新的Node v8.0.0对此进行了测试。但是,我查看了一些较旧的文档,并且至少从v0.12开始存在API,因此,假设没有任何重大改变,这应该适用于您正在运行的任何版本的Node。此外,将主机名解析为IP地址可能只是争夺战的一半。如果您尝试直接通过IP访问它们,某些网站会表现得很奇怪(或根本不会)。

答案 1 :(得分:0)

基于@ supersam654和this:我的解决方案(完整示例)带有.get请求(所有请求都带有igrnore hosts):

const dns = require("dns");
const url = require("url");

const req = (urlString, cb) => {
    const parsedUrl = url.parse(urlString);
    const hostname = parsedUrl.hostname;

    dns.resolve4(hostname, function(err, res) {
        if (err) throw err;
        console.log(`A real IP address of ${hostname} is: ${res[0]}`);
        const newUrl = urlString.replace(`${parsedUrl.protocol}//${hostname}`, `${parsedUrl.protocol}//${res[0]}`);

        https
            .get(
                newUrl,
                {
                    headers: { host: hostname },
                    servername: hostname
                },
                resp => {
                    let data = "";

                    // A chunk of data
                    resp.on("data", chunk => {
                        data += chunk;
                    });

                    // The whole response has been received. Print out the result.
                    resp.on("end", () => {
                        cb(data);
                    });
                }
            )
            .on("error", err => {
                console.log("Error request " + url + ": " + err.message);
            });
    });
};

// Example
req("https://google.com/", data => console.log(data));