解决一个历史遗留问题:博客上线后第一篇关于Nodejs的博客是——Nodejs绑定域名和反向代理;讲的是Nodejs的代理设置,目前网上的几个二级小站还在使用http-proxy模块,但没想到这些小站的一个普遍遗留问题也出自这个代理模块;问题是:通过各种已知方法获取的访问者ip始终是127.0.0.1;请不要提到os模块,os可以获取该站点的ipv4值,除了这个值之外,根本没有第二个ipv4字段!比如博客为主站,CDN为副站。proxy模块是这样的,如下,问题出在里面:varhttp=require('http'),httpProxy=require('http-proxy'),proxy=httpProxy.createProxyServer({});proxy.on('error',function(err,req,res){res.writeHead(500,{'Content-Type':'text/plain'});res.end('出错了。');});varserver=require('http').createServer(function(req,res){varhost=req.headers.host;switch(host){case'cdn.famanoder.cn':proxy.web(req,res,{target:'http://localhost:4000'});break;case'www.famanoder.cn':proxy.web(req,res,{target:'http://localhost:3000'});break;默认值:proxy.web(req,res,{target:'http://localhost:3000'});}});server.listen(80);这里新建一个服务器监听80端口,然后根据所有请求的主机,将请求代理到目标站点;如果访问首页http://famanoder.com,会被代理到服务器3000端口的站点,也就是说,我只是觉得访问首页的时候直接访问3000端口,但是在其实是通过一个额外的服务器代理,所以我在所有站点得到的ip永远都是127.0.0.1,因为代理之后的域名从famanoder.com变成了localhost;从上面的代理设置,我们可以看出两个问题:1、这里新建的服务器是多余的;2.代理设置中不能包含所有站点;2.5.对不起,请原谅我是一个不完美的孩子;既然这台服务器是多余的,那先把它拆掉;既然代理设置中不能包含所有站点,那么就让博客作为主站点监听80端口;那么应该是在主站副站下发了,结果发现主站监听80端口后,可以通过express的req.ip获取访问者的ip。如上,二级站点现在是代理转发的,所以还是得不到真实访问者的ip;既然现在主站可以拿到ip,而副站是主站分发的,那么通过在转发前设置转发请求的header,副站可以从header中得到ip是从主站传过来的?在express中,这个代理设置现在可以当作一个中间件,访问者的ip可以通过请求头带过来:app.use(function(req,res,next){console.log(req.ip);varproxy=httpProxy.createProxyServer({headers:{'x-forward-ip':req.ip.match(/([\w\.]+)/g)[1]}});proxy.on('错误',function(err,req,res){res.writeHead(500,{'Content-Type':'text/plain'});res.end('出错了。');});varhost=req.headers.host;开关(host){case'cdn.famanoder.cn':proxy.web(req,res,{target:'http://localhost:4000'});休息;default:next();//主站将不再转发,需要next()!!!}});如上:添加代理设置的headers项,二级站点会使用req.header('x-forward-ip')获取访问者的ip;使用http-proxy解决跨域问题:如果a.com去请求b.com接口,就涉及到跨域问题。除了jsonp,还可以通过http-proxy设置代理,直接请求a.com,然后代理将a.com转发到b.com,实现跨域;case'a.com':proxy.web(req,res,{target:'http://b.com'});休息;因为跨域问题只存在于前端,后端根本不涉及跨域问题;现在感觉http-proxy是通过http.request转发的,可能是为了切换host;原文来自:花满楼(http://famanoder.com/bokes)
