關於Nodejs裏代理設置的問題

解決一個歷史遺留問題:前端

博客上線後第一篇關於Nodejs的博客就是——Nodejs綁定域名與反向代理;是關於Nodejs的代理設置,到如今爲止線上幾個二級小站也仍是在使用那個http-proxy模塊,卻怎麼也沒想到,這些小站的一個共同的遺留問題也源自這個代理模塊;問題在於:用已知的各類方式獲取到的訪問者的ip永遠爲127.0.0.1;拜託不要提os模塊了,os能夠獲取本站ipv4的值,除此值之外,根本沒有第二個ipv4的字段好嘛!node

好比以博客爲主站,cdn爲二級站點,代理模塊是這樣的,像下面這樣,問題就在其中:web

var http = 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('Something went wrong.');
});
var server = require('http').createServer(function(req, res) {
    var host = 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;
         default:
            proxy.web(req, res, { target: 'http://localhost:3000' });
    }
});
server.listen(80);

這裏是新建了一個server來監聽80端口,而後根據全部請求的host,將請求代理到目標站點;若是訪問首頁http://famanoder.com那麼將會被代理到服務器上的3000端口的站點,也就是說,我只是自認爲我訪問首頁就是直接訪問3000端口,而實際上是經過一個額外的server代理過去的,因此我在全部站點裏獲取到的ip永遠爲127.0.0.1,由於代理過來後域從famanoder.com變爲了localhost;express

從上面的代理設置,能夠看出兩個問題:json

一、這裏新建的一個server是多餘的;後端

二、不能將全部站點包括在代理設置內;跨域

2.五、抱歉,請原諒我這個不完美的小孩;服務器

既然這個server是多餘的,那麼先將其去掉;app

既然不能將全部站點包括在代理設置內,那麼就留下博客作主站監聽80端口;jsonp

那麼就應該在主站裏分發二級站點了,事實也證實主站裏監聽80端口後,經過express的req.ip就能獲取到訪問者的ip了,同上,二級站點如今是被代理轉發的,因此依然拿不到真實的訪問者的ip;

既然主站如今能夠拿到ip,二級站點又是由主站分發出去的,那麼在轉發以前經過設置轉發請求的header,二級站點從header上不就能夠拿到從主站傳過來的ip了嗎!

在express裏,如今能夠將這個代理設置做爲一箇中間件來對待,將訪問者的ip由請求header帶過去:

app.use(function(req,res,next){
  console.log(req.ip);
    var proxy = httpProxy.createProxyServer({
      headers:{
        'x-forward-ip':req.ip.match(/([\w\.]+)/g)[1]
      }
    });
    proxy.on('error', function (err, req, res) {
     res.writeHead(500, {
     'Content-Type': 'text/plain'
     });
     res.end('Something went wrong.');
    });
    var host = req.headers.host;
     switch (host){
      case 'cdn.famanoder.cn': 
        proxy.web(req, res, { target: 'http://localhost:4000' });
      break;
       default:  
        next();//主站再也不被轉發,next()是必需的!!!
     }
});

如上:添加了代理設置的headers項,二級站點將由req.header('x-forward-ip')來獲取訪問者的ip;

用http-proxy解決跨域問題:

若是a.com要請求b.com的接口,涉及到跨域問題,除了jsonp以外,經過http-proxy設置代理,能夠直接請求a.com,而後由proxy將a.com轉發到b.com實現跨域;

case 'a.com':
    proxy.web(req, res, { target: 'http://b.com' });
break;

由於跨域問題只存在於前端,後端根本不涉及到跨域問題;如今感受http-proxy是經過http.request來實現的轉發,可能就是切換host;

原文來自:花滿樓(http://famanoder.com/bokes

相關文章
相關標籤/搜索