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做中转服务器转发接口,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对毛票票网站的支持!