http-proxy代理nodejs服务器转发跨域资源
作者:秋了秋 发表时间:2017年08月29日
跨域问题是让前端很恼火的一件事情,这主要是浏览器为了安全所进行的限制,在原生native应用和服务器端是不存在跨域情况的。上篇文章已经说了,如果我们要使用存在跨域(以第三方网站来阐述,下同)的数据,那么可以通过后端发请求,去爬取页面的内容(简称爬虫),再把爬到的内容返回给前端。这是获取页面内容。接口数据也一样,后端发请求到第三方api系统获取返回的内容再json化后返回给前端。这些都是基于字符串的简单数据,即使不用代理模块也可以做。然而对于流媒体数据就比较棘手了,我们引用nodejs的http-proxy模块来做实时请求转发,让请求看起来就只是变了个请求url,返回hreader和数据依旧是原第三方网站的header和数据,不用我们做任何处理,成功逃过浏览器的火眼金睛。
http-proxy使用细则:
首先要安装该模块:
npm install http-proxy --save
在应用启动入口文件(一般为app.js)引入模块:
var http = require("http"); var httpProxy = require('http-proxy'); var proxy = httpProxy.createProxyServer({});
监听服务器出错:
proxy.on('error', function (err, req, res) { res.writeHead(500, { 'Content-Type': 'text/plain' }); res.end('500'); })
在应用启动入口文件部署代理服务器,一般的,我们只是用来做部分转发,即作工具的使用,可以在具体的某个请求中使用代理:
app.get(/.*?\.mp3$/, proxyer);//把请求MP3的链接使用代理 function proxyer(req,res,next){ delete req.headers.host;//一定要把host删除,不然会出现404,我在这里踩了好久的坑! proxy.web(req, res, {target: 'http://fs.open.kugou.com'}); }
如果当作另一个服务器来运行,我们可以在加一个代理服务。只要端口号不跟原应用端口不冲突就可以:
var server = http.createServer(function(req, res) {
var host = req.headers.host, ip = req.headers['x-forwarded-for'] || req.connection.remoteAddress;
console.log("client ip:" + ip + ", host:" + host);
delete req.headers.host;
switch(host){
case 'netblog.cn':
//把请求url的host主机为netblog.cn 80 端口的请求转发到http://fs.open.kugou.com去获取数据,可以理解为直接把请求地址 //netblog.cn替换成http://fs.open.kugou.com
proxy.web(req, res, {target: 'http://fs.open.kugou.com'});
break;
case 'music.netblog.site':
proxy.web(req, res, {target: 'http://localhost:3000'});
break;
default:
res.writeHead(200, {
'Content-Type': 'text/plain'
});
res.end('你访问的是代理服务器,但是代理域名规则找不到你的请求!');
}
});
console.log("proxy listening on port 80")
server.listen(80);
至此,代理服务器已经搭建好了,现在就只管发请求了!从上面那段代码可以看出,当多个域名绑定到这个服务器上时,不同域名可以访问不同的端口应用达到一台服务器运行多个网站的目的。如此完美!这里我们不详细说这个,来看看它的实现过程吧:
比如前端网站的域名是netblog.cn,前端发起请求为“/music/123.mp3”,服务器收到请求就会转发请求到http://fs.open.kugou.com/music/123.mp3,到第三方网站去了。也就是我们访问//netblog.cn/music/123.mp3实际上访问的是http://fs.open.kugou.com/music/123.mp3,从而实现了发起一个服务器不存在的url或路由访问了一个第三方存在的资源。简直装得一模一样!跨域问题自然就迎刃而解。