Node做中转服务器转发接口
程序员文章站
2022-04-09 21:48:31
由于项目在做前后端分离,牵扯跨域和夸协议问题,临时抱佛脚,选择用nodejs做中转,我想应该好多人都用它。但是做普通的表单转发没啥问题,当处理附件上传转发时,各种蛋疼,已解...
由于项目在做前后端分离,牵扯跨域和夸协议问题,临时抱佛脚,选择用nodejs做中转,我想应该好多人都用它。但是做普通的表单转发没啥问题,当处理附件上传转发时,各种蛋疼,已解决!
1.项目比较特殊,后台拥有两个平台,一个java一个donet,比较鸡肋,具体什么原因就不解释了。
2.当做node转发时,刚开始没有转发文件的操作,就做的很简单,用户传过来啥就,拦截到,进行转发,一切都很ok!
3.文件转发,就很麻烦。我的思路,将用户上传的文件存到node服务器。使用formidable 。
通过npm安装:
npm install formidable@latest
使用它进行文件转存,保存到临时目录得到文件信息。
再通过文件包重组。进行上传。注意此处上传必须遵循w3c上传文件表单标准,具体自己查资料。
其实思路很简单,但是实际操作起来还是挺麻烦,我中间也趟了好多坑,也是自己node不成熟,毕竟只是用来做中转!
直接上代码吧:看代码还是清晰:
server.js,用于启动服务并转发。
var http = require("http"); var url = require("url"); var fs = require('fs'); const querystring = require("querystring"); var path = require('path'); var formidable = require('formidable'), os = require('os'), util = require('util'); var config = require('./config').types; // var netserverurlflag = require('./config').netserverurlflag; var netserverhost = require('./config').netserverhost; var netserverport = require('./config').netserverport; var javaserverurlflag = require('./config').javaserverurlflag; var javaserverhost = require('./config').javaserverhost; var javaserverport = require('./config').javaserverport; var fileserverurlflag = require('./config').fileserverurlflag; var webapp = require('./config').webapp; var port = require('./config').webport; /** * 上传文件 * @param files 经过formidable处理过的文件 * @param req httprequest对象 * @param postdata 额外提交的数据 */ function uploadfile(files, req, postdata) { var boundarykey = math.random().tostring(16); var enddata = '\r\n----' + boundarykey + '--'; var fileslength = 0, content; // 初始数据,把post过来的数据都携带上去 content = (function (obj) { var rslt = []; 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('')); }); return rslt.join(''); })(postdata); // 组装数据 object.keys(files).foreach(function (key) { if (!files.hasownproperty(key)) { delete files.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 = new buffer(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)); // 执行上传 var allfiles = object.keys(files); var filenum = allfiles.length; var uploadedcount = 0; allfiles.foreach(function (key) { req.write(files[key].contentbinary); console.log("files[key].path:" + files[key][1].path); var filestream = 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 }); }); } var server = http.createserver(function (request, response) { var clienturl = request.url; var url_parts = url.parse(clienturl); //解析路径 var pathname = url_parts.pathname; var sreq = request; var sres = response; // .net 转发请求 if (pathname.match(netserverurlflag) != null) { var clienturl2 = clienturl.replace("/" + netserverurlflag, ''); console.log(".net转发请求......" + clienturl2); var pramsjson = ''; sreq.on("data", function (data) { pramsjson += data; }).on("end", function () { var contenttype = request.headers['content-type']; if (contenttype == undefined || contenttype == null || contenttype == '') { var opt = { host: netserverhost, //跨域访问的主机ip port: netserverport, path: clienturl2, method: request.method, headers: { 'content-length': buffer.bytelength(pramsjson) } } } else { var opt = { 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); var body = ''; var req = 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"); var clienturl2 = clienturl.replace("/" + javaserverurlflag, ''); console.log(".java转发请求......http://" + javaserverhost + ":" + javaserverport + "" + clienturl2); var prams = ''; sreq.on("data", function (data) { prams += data; }).on("end", function () { console.log("client pramsjson>>>>>" + prams); const postdata = prams; console.log("client pramsjson>>>>>" + postdata); var contenttype = request.headers['content-type']; if (contenttype == undefined || contenttype == null || contenttype == '') { var opt = { host: javaserverhost, //跨域访问的主机ip port: javaserverport, path: "/hrrp" + clienturl2, method: request.method, headers: { 'content-length': buffer.bytelength(postdata) } } } else { var opt = { host: javaserverhost, //跨域访问的主机ip port: javaserverport, path: "/hrrp" + clienturl2, method: request.method, headers: { 'content-type': request.headers['content-type'], 'content-length': buffer.bytelength(postdata) } } } var body = ''; console.log('method', opt.method); var req = 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(); }) } else if (pathname.match(fileserverurlflag) != null) { //文件拦截保存到本地 var form = new formidable.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 () { // var clienturl2 = clienturl.replace("/" + fileserverurlflag, ''); var opt = { host: netserverhost, //跨域访问的主机ip port: netserverport, path: clienturl2, method: request.method } var body = ''; var req = 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 { var realpath = path.join(webapp, pathname); //这里设置自己的文件名称; var ext = path.extname(realpath); ext = ext ? ext.slice(1) : 'unknown'; fs.exists(realpath, function (exists) { //console.log("file is exists:"+exists+" file path: " + realpath + ""); if (!exists) { response.writehead(404, { 'content-type': 'text/plain' }); response.write("this request url " + pathname + " was not found on this server."); 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 { var contenttype = config[ext] || "text/plain"; response.writehead(200, { 'content-type': contenttype }); response.write(file, "binary"); response.end(); } }); } }); } }); server.listen(port); console.log("server runing at port: " + 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做中转服务器转发接口,希望对大家有所帮助