NodeJS,绕过 linux hosts 文件
NodeJS, bypass linux hosts file
NodeJS 有没有办法绕过 linux 的 /etc/hosts 文件?
例如,如果我的主机文件中有一个条目,例如:
127.0.0.1example.com
如何从 NodeJS 访问 'real' example.com?
我暂时不想修改/etc/hosts来做这个,因为它会带来一些问题并且不是一个干净的解决方案。
提前致谢!
起初我认为这是不可能的,但后来我偶然发现了一种 ignore the hosts file on Linux. Additionally, I found a DNS API 内置到 Node 中的方法。基本上,默认情况下,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 对此进行了测试。但是,我查看了一些较旧的文档,发现 API 至少从 v0.12 开始就存在,因此,假设没有发生重大变化,这应该适用于您碰巧 运行 的任何版本的 Node。此外,将主机名解析为 IP 地址可能只是成功的一半。如果您尝试直接通过 IP 访问某些网站,它们的行为会很奇怪(或根本不会)。
基于@supersam654 和 :我的解决方案(完整示例)带有 .get
请求(忽略 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));
NodeJS 有没有办法绕过 linux 的 /etc/hosts 文件?
例如,如果我的主机文件中有一个条目,例如: 127.0.0.1example.com
如何从 NodeJS 访问 'real' example.com?
我暂时不想修改/etc/hosts来做这个,因为它会带来一些问题并且不是一个干净的解决方案。
提前致谢!
起初我认为这是不可能的,但后来我偶然发现了一种 ignore the hosts file on Linux. Additionally, I found a DNS API 内置到 Node 中的方法。基本上,默认情况下,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 对此进行了测试。但是,我查看了一些较旧的文档,发现 API 至少从 v0.12 开始就存在,因此,假设没有发生重大变化,这应该适用于您碰巧 运行 的任何版本的 Node。此外,将主机名解析为 IP 地址可能只是成功的一半。如果您尝试直接通过 IP 访问某些网站,它们的行为会很奇怪(或根本不会)。
基于@supersam654 和 .get
请求(忽略 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));