NodeJS中有没有办法绕过linux的/ etc / hosts文件?
例如,如果我在hosts文件中有一个条目,例如: 127.0.0.1 example.com
我如何从NodeJS访问'real'example.com?
我不想暂时修改/ etc / hosts来执行此操作,因为它可能会带来一些问题并且不是一个干净的解决方案。
提前致谢!
答案 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));