那么经过上面的分析,我们可以通过nodejs中的http-proxy模块来实现,在使用这个之前要做的是对请求类型的一些判断,即请求Js/css/jpg等这些文件时,返回的response信息类型是什么,于是有了下面的代码(也是我自己写的一个content-type模块)content-type.js:
/* content type by subying [email protected] 根据后缀 转换 content-type */ var getContentType = function(ext){ var contentType = ''; switch(ext){ case ".html": contentType= "text/html"; break; case ".js": contentType="text/javascript"; break; case ".css": contentType="text/css"; break; case ".gif": contentType="image/gif"; break; case ".jpg": contentType="image/jpeg"; break; case ".png": contentType="image/png"; break; case ".ico": contentType="image/icon"; break; default: contentType="application/octet-stream"; } return contentType; }; module.exports = getContentType;
有了这个还需要用到nodejs里面的一个模块:http-proxy,npm地址为 https://www.npmjs.org/package/http-proxy。那么前面有说过,将静态资源分离,就会用到虚拟目录,要怎么判断它是静态资源呢?这就是我为什么要用nodejs实现反向代理的原因了,因为我可以自己自由的定义,就是一个if的问题而已。本人习惯将静态资源放到了一个res的文件夹里,所以我只要判断请求里面存在’/res/’这个目录,我就知道是请求静态资源了。判断是请求静态资源后,再找到项目的物理路径比如’E:\teset\res’,再用fs模块读取出来,返回到客户端。那么其他的请求就通过本地的其他服务器来实现。本例中用到的代理方法是http-proxy的web方法,http-proxy更多的用法可以去查阅上面给出来的npm地址。
/* http-proxy */ var http = require('http') ,httpProxy = require('http-proxy') //http-proxy ,proxy = httpProxy.createProxyServer({}) ,fs = require('fs') ,path = require('path') ,getConType = require('./content-type')//自己定义 根据后缀转换Content-Type ; var server = http.createServer(function(req, res) { var _url = req.url //获取请求的url ,_file ,_localPath ,_localFile ,_ext ,_stream ; if(_url.indexOf('/res/')>-1){ _file = _url.replace(/\?.*/ig,''); _ext = path.extname(_file); // 文件扩展 //判断是否为js文件 if(_ext === '.js'){ _file = _file.replace('res/js/','res/src_js/'); } //转换成本地路径 _localPath = 'E:/web/angularjs/'; _localFile = _localPath+_file; //判断文件是否存在 if(fs.existsSync(_localFile)){//如果文件存在 res.writeHead(200, {"Content-Type": getConType(_ext) }); _stream = fs.createReadStream(_localFile, {flags : "r", encoding : null});//只读模式 读取文件内容 _stream.on('error',function(){//如果读取错误 返回404 res.writeHead(404, {"Content-Type": "text/html"}); res.end("<h1>404 Read Error</h1>"); }); _stream.pipe(res);//连接文件流和http返回流的管道,用于返回实际Web内容 _stream.on('end',function(){ _stream = null; }) }else{//返回404错误 res.writeHead(404, {"Content-Type": "text/html"}); res.end("<h1>404 Not Found</h1>"); } }else{ proxy.web(req, res, { target: 'http://127.0.0.1:81' }); } }); console.log("listening on port 80") server.listen(80);