Node做中转服务器转发接口
由于项目在做前后端分离,牵扯跨域和夸协议问题,临时抱佛脚,选择用nodejs做中转,我想应该好多人都用它。但是做普通的表单转发没啥问题,当处理附件上传转发时,各种蛋疼,已解决!
1.项目比较特殊,后台拥有两个平台,一个java一个donet,比较鸡肋,具体什么原因就不解释了。
2.当做node转发时,刚开始没有转发文件的操作,就做的很简单,用户传过来啥就,拦截到,进行转发,一切都很ok!
3.文件转发,就很麻烦。我的思路,将用户上传的文件存到node服务器。使用formidable 。
通过npm安装:
npminstallformidable@latest
使用它进行文件转存,保存到临时目录得到文件信息。
再通过文件包重组。进行上传。注意此处上传必须遵循w3c上传文件表单标准,具体自己查资料。
其实思路很简单,但是实际操作起来还是挺麻烦,我中间也趟了好多坑,也是自己node不成熟,毕竟只是用来做中转!
直接上代码吧:看代码还是清晰:
server.js,用于启动服务并转发。
varhttp=require("http");
varurl=require("url");
varfs=require('fs');
constquerystring=require("querystring");
varpath=require('path');
varformidable=require('formidable'),
os=require('os'),
util=require('util');
varconfig=require('./config').types;//
varnetServerUrlFlag=require('./config').netServerUrlFlag;
varnetServerhost=require('./config').netServerhost;
varnetServerport=require('./config').netServerport;
varjavaServerUrlFlag=require('./config').javaServerUrlFlag;
varjavaServerhost=require('./config').javaServerhost;
varjavaServerport=require('./config').javaServerport;
varfileServerUrlFlag=require('./config').fileServerUrlFlag;
varwebapp=require('./config').webapp;
varPORT=require('./config').webport;
/**
*上传文件
*@paramfiles经过formidable处理过的文件
*@paramreqhttpRequest对象
*@parampostData额外提交的数据
*/
functionuploadFile(files,req,postData){
varboundaryKey=Math.random().toString(16);
varendData='\r\n----'+boundaryKey+'--';
varfilesLength=0,content;
//初始数据,把post过来的数据都携带上去
content=(function(obj){
varrslt=[];
Object.keys(obj).forEach(function(key){
arr=['\r\n----'+boundaryKey+'\r\n'];
arr.push('Content-Disposition:form-data;name="'+obj[key][0]+'"\r\n\r\n');
arr.push(obj[key][1]);
rslt.push(arr.join(''));
});
returnrslt.join('');
})(postData);
//组装数据
Object.keys(files).forEach(function(key){
if(!files.hasOwnProperty(key)){
deletefiles.key;
return;
}
content+='\r\n----'+boundaryKey+'\r\n'+
'Content-Type:application/octet-stream\r\n'+
'Content-Disposition:form-data;name="'+files[key][0]+'";'+
'filename="'+files[key][1].name+'";\r\n'+
'Content-Transfer-Encoding:binary\r\n\r\n';
files[key].contentBinary=newBuffer(content,'utf-8');;
filesLength+=files[key].contentBinary.length+fs.statSync(files[key][1].path).size;
});
req.setHeader('Content-Type','multipart/form-data;boundary=--'+boundaryKey);
req.setHeader('Content-Length',filesLength+Buffer.byteLength(endData));
//执行上传
varallFiles=Object.keys(files);
varfileNum=allFiles.length;
varuploadedCount=0;
allFiles.forEach(function(key){
req.write(files[key].contentBinary);
console.log("files[key].path:"+files[key][1].path);
varfileStream=fs.createReadStream(files[key][1].path,{bufferSize:4*1024});
fileStream.on('end',function(){
//上传成功一个文件之后,把临时文件删了
fs.unlink(files[key][1].path);
uploadedCount++;
if(uploadedCount==fileNum){
//如果已经是最后一个文件,那就正常结束
req.end(endData);
}
});
fileStream.pipe(req,{end:false});
});
}
varserver=http.createServer(function(request,response){
varclientUrl=request.url;
varurl_parts=url.parse(clientUrl);//解析路径
varpathname=url_parts.pathname;
varsreq=request;
varsres=response;
//.net转发请求
if(pathname.match(netServerUrlFlag)!=null){
varclientUrl2=clientUrl.replace("/"+netServerUrlFlag,'');
console.log(".net转发请求......"+clientUrl2);
varpramsJson='';
sreq.on("data",function(data){
pramsJson+=data;
}).on("end",function(){
varcontenttype=request.headers['content-type'];
if(contenttype==undefined||contenttype==null||contenttype==''){
varopt={
host:netServerhost,//跨域访问的主机ip
port:netServerport,
path:clientUrl2,
method:request.method,
headers:{
'Content-Length':Buffer.byteLength(pramsJson)
}
}
}else{
varopt={
host:netServerhost,//跨域访问的主机ip
port:netServerport,
path:clientUrl2,
method:request.method,
headers:{
'Content-Type':request.headers['content-type'],
'Content-Length':Buffer.byteLength(pramsJson)
}
}
}
console.log('method',opt.method);
varbody='';
varreq=http.request(opt,function(res){
res.on('data',function(data){
body+=data;
}).on('end',function(){
response.write(body);
response.end();
});
}).on('error',function(e){
response.end('内部错误,请联系管理员!MSG:'+e);
console.log("error:"+e.message);
})
req.write(pramsJson);
req.end();
})
}else
//java转发请求
if(pathname.match(javaServerUrlFlag)!=null){
response.setHeader("Content-type","text/plain;charset=UTF-8");
varclientUrl2=clientUrl.replace("/"+javaServerUrlFlag,'');
console.log(".java转发请求......http://"+javaServerhost+":"+javaServerport+""+clientUrl2);
varprams='';
sreq.on("data",function(data){
prams+=data;
}).on("end",function(){
console.log("clientpramsJson>>>>>"+prams);
constpostData=prams;
console.log("clientpramsJson>>>>>"+postData);
varcontenttype=request.headers['content-type'];
if(contenttype==undefined||contenttype==null||contenttype==''){
varopt={
host:javaServerhost,//跨域访问的主机ip
port:javaServerport,
path:"/hrrp"+clientUrl2,
method:request.method,
headers:{
'Content-Length':Buffer.byteLength(postData)
}
}
}else{
varopt={
host:javaServerhost,//跨域访问的主机ip
port:javaServerport,
path:"/hrrp"+clientUrl2,
method:request.method,
headers:{
'Content-Type':request.headers['content-type'],
'Content-Length':Buffer.byteLength(postData)
}
}
}
varbody='';
console.log('method',opt.method);
varreq=http.request(opt,function(res){
//console.log("response:"+res.statusCode);
res.on('data',function(data){
body+=data;
}).on('end',function(){
response.write(body);
response.end();
//console.log("end:>>>>>>>"+body);
});
}).on('error',function(e){
response.end('内部错误,请联系管理员!MSG:'+e);
console.log("error:"+e.message);
})
req.write(postData);
req.end();
})
}elseif(pathname.match(fileServerUrlFlag)!=null){
//文件拦截保存到本地
varform=newformidable.IncomingForm(),
files=[],
fields=[];
form.uploadDir=os.tmpdir();
form.on('field',function(field,value){
console.log(field,value);
fields.push([field,value]);
}).on('file',function(field,file){
console.log(field,file);
files.push([field,file]);
}).on('end',function(){
//
varclientUrl2=clientUrl.replace("/"+fileServerUrlFlag,'');
varopt={
host:netServerhost,//跨域访问的主机ip
port:netServerport,
path:clientUrl2,
method:request.method
}
varbody='';
varreq=http.request(opt,function(res){
res.on('data',function(data){
body+=data;
}).on('end',function(){
response.write(body);
response.end();
});
}).on('error',function(e){
response.end('内部错误,请联系管理员!MSG:'+e);
console.log("error:"+e.message);
})
//文件上传
uploadFile(files,req,fields);
});
form.parse(sreq);
}
else{
varrealPath=path.join(webapp,pathname);//这里设置自己的文件名称;
varext=path.extname(realPath);
ext=ext?ext.slice(1):'unknown';
fs.exists(realPath,function(exists){
//console.log("fileisexists:"+exists+"filepath:"+realPath+"");
if(!exists){
response.writeHead(404,{
'Content-Type':'text/plain'
});
response.write("ThisrequestURL"+pathname+"wasnotfoundonthisserver.");
response.end();
}else{
fs.readFile(realPath,"binary",function(err,file){
if(err){
response.writeHead(500,{
'Content-Type':'text/plain'
});
//response.end(err);
response.end("内部错误,请联系管理员");
}else{
varcontentType=config[ext]||"text/plain";
response.writeHead(200,{
'Content-Type':contentType
});
response.write(file,"binary");
response.end();
}
});
}
});
}
});
server.listen(PORT);
console.log("Serverruningatport:"+PORT+".");
config.js,用于配置。
exports.types={
"css":"text/css",
"gif":"image/gif",
"html":"text/html",
"htm":"text/html",
"ico":"image/x-icon",
"jpeg":"image/jpeg",
"jpg":"image/jpeg",
"js":"text/javascript",
"json":"application/json",
"pdf":"application/pdf",
"png":"image/png",
"svg":"image/svg+xml",
"swf":"application/x-shockwave-flash",
"tiff":"image/tiff",
"txt":"text/plain",
"wav":"audio/x-wav",
"wma":"audio/x-ms-wma",
"wmv":"video/x-ms-wmv",
"xml":"text/xml"
};
exports.netServerUrlFlag="NETSERVER";
exports.netServerhost="";
exports.netServerport="";
exports.javaServerUrlFlag="JAVASERVER";
exports.javaServerhost="";//转发的地址
exports.javaServerport="";//转发的端口
exports.fileServerUrlFlag="FileUpload";
exports.webapp="public";//项目目录
exports.webport="82";//项目启动端口
总结
以上所述是小编给大家介绍的Node做中转服务器转发接口,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对毛票票网站的支持!