04月02, 2014

Node.js下通过配置host访问URL

介绍

日常开发中,我们经常会遇到需要绑定host来访问一个URL。比如:Windows下可以修改C:/Windows/System32/drivers/etc/hosts文件来绑定host,Linux和Mac下可以修改/etc/hosts文件来绑定host。

程序修改host文件

那程序里有办法通过host来访问URL么? (这里的host指的是系统对应的host文件,如下同)

既然人工可以修改host文件来访问,那程序也可以来修改这个文件达到同样的目的。Node.js下就有hosts-group模块来实现这个功能。

但有个问题来了,修改host文件需要sudo权限,比如:人工操作需要sudo vim /etc/hosts,但程序一般都是在非root账号下运行的。 除非用root账号起个修改host的服务,供其他地方调用。

程序里需要先调用这个服务设置host,请求完成后在调用该服务去除绑定的host。如果同时有多个或者同一个域名绑定不同的ip,还需要加上锁的机制,防止冲突。并且这种方式会大大影响请求的时间。

程序通过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的简单实现,其他语言都是类似的。

本文链接:http://welefen.com/post/request-url-by-vhost-in-node.js.html

-- EOF --

Comments

评论加载中...

注:如果长时间无法加载,请针对 disq.us | disquscdn.com | disqus.com 启用代理。