日常开发中,我们经常会遇到需要绑定host来访问一个URL。比如:Windows下可以修改C:/Windows/System32/drivers/etc/hosts
文件来绑定host,Linux和Mac下可以修改/etc/hosts
文件来绑定host。
那程序里有办法通过host来访问URL么? (这里的host指的是系统对应的host文件,如下同)
既然人工可以修改host文件来访问,那程序也可以来修改这个文件达到同样的目的。Node.js下就有hosts-group模块来实现这个功能。
但有个问题来了,修改host文件需要sudo权限,比如:人工操作需要sudo vim /etc/hosts,但程序一般都是在非root账号下运行的。 除非用root账号起个修改host的服务,供其他地方调用。
程序里需要先调用这个服务设置host,请求完成后在调用该服务去除绑定的host。如果同时有多个或者同一个域名绑定不同的ip,还需要加上锁的机制,防止冲突。并且这种方式会大大影响请求的时间。
我们知道,访问一个URL,都是先通过DNS解析到ip,然后通过ip去访问的。修改host文件也是通过这个原理。 既然是通过ip来访问的,那我们把URL中的hostname部分修改为配置的ip,就能访问到绑定的机器了。 比如:http://www.baidu.com/xxx => http://10.18.1.100/xxx,这样访问baidu.com/xxx其他就访问到10.18.1.100机器。
但一般一台开发机都是配置了多个域名的,这时候我们就需要在请求的header中加上Host: www.baidu.com来标识访问哪个域名。
既然知道了其他的原理,那么实现就很简单了。 通过如下的方式就能把URL解析为对应的ip:
global.getParsedUrl = function(requestUrl, host){
if (requestUrl.indexOf("http") !== 0) {
requestUrl = "http://" + requestUrl;
};
var urlInfo = url.parse(requestUrl);
host = host || urlInfo.hostname;
var ext = (urlInfo.port ? (":" + urlInfo.port) : "") + (urlInfo.pathname || "") + (urlInfo.query ? ("?" + urlInfo.query) : "");
return {
url: urlInfo.protocol + "//" + host + ext,
host: urlInfo.hostname
}
}
拿到解析后的url和host,就可以用下面的方式来访问了。
var url = "http://www.baidu.com/xxx";
var parsed = getParsedUrl(url, "10.18.1.10");
var request = require("request"); //这里使用request模块进行http访问
request.get({
url: parsed.url,
headers: {
"Host": parsed.host
}
}, function(error, response, body){
})
这里只是Node.js的简单实现,其他语言都是类似的。
Copyright© 2013-2020
All Rights Reserved 京ICP备2023019179号-8