• Node做中转服务器,转发接口


    2019年08月16日,建议使用nginx做转发。毕竟nginx更擅长。

    转发代码段:

     1 server {
     2     listen       80;
     3     server_name   xxx.xxx.cn;
     4     location  ~* /eureka {
     5             rewrite /eureka/(.*) /$1 break;
     6             rewrite /eureka /$1 break;
     7             proxy_pass http://172.16.49.229:8001;
     8     }
     9     location  ~* /admin {
    10             rewrite /admin/(.*) /$1 break;
    11             rewrite /admin /$1 break;
    12             proxy_pass http://172.16.49.229:8001;
    13     }
    14     location  ~* /crm {
    15             rewrite /crm/(.*) /$1 break;
    16             rewrite /crm /$1 break;
    17             proxy_pass http://172.16.49.229:8001;
    18     }
    19     location  ~* /config-server {
    20             rewrite /config-server/(.*) /$1 break;
    21             rewrite /config-server /$1 break;
    22             proxy_pass http://172.16.49.229:8001;
    23     }
    24 
    25 }
    View Code

    2018年04月11日,转发修改。支持文件下载。

    返回值处理代码修改!所有返回值以文件流的方式接收,支持附件下载和普通数据。你的框架要是可以直接访问访问文件服务器,那就直连了,要是像我一样,文件服务器在内网,只有前端服务器开了内网,那你就得和我一样,做文件下载转发,欢迎您,提供更好方案!

     1   var body = '';
     2             var req = http.request(opt, function (res) {
     3                 res.setEncoding('binary');  //二进制binary 
     4                 res.on('data', function (data) {
     5                     body += data;
     6                 }).on('end', function () {
     7                     response.writeHead(200, res.headers);
     8                     response.write(body, "binary");
     9                     response.end();
    10                 });
    11             }).on('error', function (e) {
    12                 response.end('内部错误,请联系管理员!MSG:' + e);
    13                 console.log("error: " + e.message);
    14             })
    View Code

    查询各种资料,和整理网上一哥们不完整的接口。做成,可以使用的转发服务! 

    由于项目在做前后端分离,牵扯跨域和夸协议问题,临时抱佛脚,选择用nodejs做中转,我想应该好多人都用它。但是做普通的表单转发没啥问题,当处理附件上传转发时,各种蛋疼,已解决!

    1.项目比较特殊,后台拥有两个平台,一个java一个donet,比较鸡肋,具体什么原因就不解释了。

    2.刚开始没有转发文件的操作,就做的很简单,用户传过来啥就,拦截到,进行转发,一切都很ok!

    3.当遇到文件转发时,就很麻烦。我的思路,将用户上传的文件存到node服务器。使用formidable  。

    通过npm安装:

    npm install formidable@latest
    

      使用它进行文件转存,保存到临时目录得到文件信息。

    再通过文件包重组。进行上传。注意此处上传必须遵循w3c上传文件表单标准,具体自己查资料。

    其实思路很简单,但是实际操作起来还是挺麻烦,我中间也趟了好多坑,也是自己node不成熟,毕竟只是用来做中转!

      

    直接上代码吧:看代码还是清晰: 

    server.js,用于启动服务并转发。

      1 var http = require("http");
      2 var url = require("url");
      3 var fs = require('fs');
      4 const querystring = require("querystring");
      5 var path = require('path');
      6 var formidable = require('formidable'),
      7     os = require('os'),
      8     util = require('util');
      9 
     10 var config = require('./config').types; //
     11 
     12 var netServerUrlFlag = require('./config').netServerUrlFlag;
     13 var netServerhost = require('./config').netServerhost;
     14 var netServerport = require('./config').netServerport;
     15 
     16 var javaServerUrlFlag = require('./config').javaServerUrlFlag;
     17 var javaServerhost = require('./config').javaServerhost;
     18 var javaServerport = require('./config').javaServerport;
     19 
     20 var fileServerUrlFlag = require('./config').fileServerUrlFlag;
     21 
     22 var webapp = require('./config').webapp;
     23 var PORT = require('./config').webport;
     24 /**
     25  * 上传文件
     26  * @param files     经过formidable处理过的文件
     27  * @param req        httpRequest对象
     28  * @param postData    额外提交的数据
     29  */
     30 function uploadFile(files, req, postData) {
     31     var boundaryKey = Math.random().toString(16);
     32     var endData = '
    ----' + boundaryKey + '--';
     33     var filesLength = 0, content;
     34 
     35     // 初始数据,把post过来的数据都携带上去
     36     content = (function (obj) {
     37         var rslt = [];
     38         Object.keys(obj).forEach(function (key) {
     39             arr = ['
    ----' + boundaryKey + '
    '];
     40             arr.push('Content-Disposition: form-data; name="' + obj[key][0] + '"
    
    ');
     41             arr.push(obj[key][1]);
     42             rslt.push(arr.join(''));
     43         });
     44         return rslt.join('');
     45     })(postData); 
     46 
     47     // 组装数据
     48     Object.keys(files).forEach(function (key) {
     49         if (!files.hasOwnProperty(key)) {
     50             delete files.key;
     51             return;
     52         }
     53         content += '
    ----' + boundaryKey + '
    ' +
     54             'Content-Type: application/octet-stream
    ' +
     55             'Content-Disposition: form-data; name="' + files[key][0] + '"; ' +
     56             'filename="' + files[key][1].name + '"; 
    ' +
     57             'Content-Transfer-Encoding: binary
    
    ';
     58         files[key].contentBinary = new Buffer(content, 'utf-8');;
     59         filesLength += files[key].contentBinary.length + fs.statSync(files[key][1].path).size;
     60     });
     61     req.setHeader('Content-Type', 'multipart/form-data; boundary=--' + boundaryKey);
     62     req.setHeader('Content-Length', filesLength + Buffer.byteLength(endData));
     63 
     64     // 执行上传
     65     var allFiles = Object.keys(files);
     66     var fileNum = allFiles.length;
     67     var uploadedCount = 0;
     68     allFiles.forEach(function (key) {
     69         req.write(files[key].contentBinary);
     70         console.log("files[key].path:" + files[key][1].path);
     71         var fileStream = fs.createReadStream(files[key][1].path, { bufferSize: 4 * 1024 });
     72         fileStream.on('end', function () {
     73             // 上传成功一个文件之后,把临时文件删了
     74             fs.unlink(files[key][1].path);
     75             uploadedCount++;
     76             if (uploadedCount == fileNum) {
     77                 // 如果已经是最后一个文件,那就正常结束
     78                 req.end(endData);
     79             }
     80         });
     81         fileStream.pipe(req, { end: false });
     82     });
     83 }
     84 var server = http.createServer(function (request, response) {
     85     var clientUrl = request.url;
     86     var url_parts = url.parse(clientUrl); //解析路径
     87     var pathname = url_parts.pathname;
     88 
     89     var sreq = request;
     90     var sres = response;
     91     // .net 转发请求
     92     if (pathname.match(netServerUrlFlag) != null) {
     93         var clientUrl2 = clientUrl.replace("/" + netServerUrlFlag, '');
     94         console.log(".net转发请求......" + clientUrl2);
     95         var pramsJson = '';
     96         sreq.on("data", function (data) {
     97             pramsJson += data;
     98         }).on("end", function () {
     99             var contenttype = request.headers['content-type'];
    100             if (contenttype == undefined || contenttype == null || contenttype == '') {
    101                 var opt = {
    102                     host: netServerhost, //跨域访问的主机ip
    103                     port: netServerport,
    104                     path: clientUrl2,
    105                     method: request.method,
    106                     headers: {
    107                         'Content-Length': Buffer.byteLength(pramsJson)
    108                     }
    109                 }
    110             } else {
    111                 var opt = {
    112                     host: netServerhost, //跨域访问的主机ip
    113                     port: netServerport,
    114                     path: clientUrl2,
    115                     method: request.method,
    116                     headers: {
    117                         'Content-Type': request.headers['content-type'],
    118                         'Content-Length': Buffer.byteLength(pramsJson)
    119                     }
    120                 }
    121             }
    122             console.log('method', opt.method);
    123 
    124             var body = '';
    125             var req = http.request(opt, function (res) {
    126                 res.on('data', function (data) {
    127                     body += data;
    128                 }).on('end', function () {
    129                     response.write(body);
    130                     response.end();
    131                 });
    132             }).on('error', function (e) {
    133                 response.end('内部错误,请联系管理员!MSG:' + e);
    134                 console.log("error: " + e.message);
    135             })
    136             req.write(pramsJson);
    137             req.end();
    138         })
    139 
    140     } else
    141         // java 转发请求
    142         if (pathname.match(javaServerUrlFlag) != null) {
    143             response.setHeader("Content-type", "text/plain;charset=UTF-8");
    144 
    145             var clientUrl2 = clientUrl.replace("/" + javaServerUrlFlag, '');
    146             console.log(".java转发请求......http://" + javaServerhost + ":" + javaServerport + "" + clientUrl2);
    147             var prams = '';
    148             sreq.on("data", function (data) {
    149                 prams += data;
    150             }).on("end", function () {
    151                 console.log("client pramsJson>>>>>" + prams);
    152                 const postData = prams;
    153                 console.log("client pramsJson>>>>>" + postData);
    154                 var contenttype = request.headers['content-type'];
    155                 if (contenttype == undefined || contenttype == null || contenttype == '') {
    156                     var opt = {
    157                         host: javaServerhost, //跨域访问的主机ip
    158                         port: javaServerport,
    159                         path: "/hrrp" + clientUrl2,
    160                         method: request.method,
    161                         headers: {
    162                             'Content-Length': Buffer.byteLength(postData)
    163                         }
    164                     }
    165                 } else {
    166                     var opt = {
    167                         host: javaServerhost, //跨域访问的主机ip
    168                         port: javaServerport,
    169                         path: "/hrrp" + clientUrl2,
    170                         method: request.method,
    171                         headers: {
    172                             'Content-Type': request.headers['content-type'],
    173                             'Content-Length': Buffer.byteLength(postData)
    174                         }
    175                     }
    176                 }
    177                 var body = '';
    178 
    179                 console.log('method', opt.method);
    180                 var req = http.request(opt, function (res) {
    181                     //console.log("response: " + res.statusCode);
    182                     res.on('data', function (data) {
    183                         body += data;
    184                     }).on('end', function () {
    185                         response.write(body);
    186                         response.end();
    187                         //console.log("end:>>>>>>>" + body);
    188                     });
    189                 }).on('error', function (e) {
    190                     response.end('内部错误,请联系管理员!MSG:' + e);
    191                     console.log("error: " + e.message);
    192                 })
    193 
    194                 req.write(postData);
    195                 req.end();
    196 
    197 
    198             })
    199         } else if (pathname.match(fileServerUrlFlag) != null) {
    200             //文件拦截保存到本地
    201             var form = new formidable.IncomingForm(),
    202                 files = [],
    203                 fields = [];
    204             form.uploadDir = os.tmpdir();
    205             form.on('field', function (field, value) {
    206                 console.log(field, value);
    207                 fields.push([field, value]);
    208             }).on('file', function (field, file) {
    209                 console.log(field, file);
    210                 files.push([field, file]);
    211             }).on('end', function () {
    212                 //
    213                 var clientUrl2 = clientUrl.replace("/" + fileServerUrlFlag, '');
    214                 var opt = {
    215                     host: netServerhost, //跨域访问的主机ip
    216                     port: netServerport,
    217                     path: clientUrl2,
    218                     method: request.method
    219                 }
    220                 var body = '';
    221                 var req = http.request(opt, function (res) {
    222                     res.on('data', function (data) {
    223                         body += data;
    224                     }).on('end', function () {
    225                         response.write(body);
    226                         response.end();
    227                     });
    228                 }).on('error', function (e) {
    229                     response.end('内部错误,请联系管理员!MSG:' + e);
    230                     console.log("error: " + e.message);
    231                 })
    232                 //文件上传
    233                 uploadFile(files, req, fields);
    234             });
    235             form.parse(sreq);
    236         }
    237         else {
    238             var realPath = path.join(webapp, pathname); //这里设置自己的文件名称;
    239             var ext = path.extname(realPath);
    240             ext = ext ? ext.slice(1) : 'unknown';
    241             fs.exists(realPath, function (exists) {
    242                 //console.log("file is exists:"+exists+" file path: " + realPath + "");
    243                 if (!exists) {
    244                     response.writeHead(404, {
    245                         'Content-Type': 'text/plain'
    246                     });
    247 
    248                     response.write("This request URL " + pathname + " was not found on this server.");
    249                     response.end();
    250                 } else {
    251                     fs.readFile(realPath, "binary", function (err, file) {
    252                         if (err) {
    253                             response.writeHead(500, {
    254                                 'Content-Type': 'text/plain'
    255                             });
    256                             //response.end(err);
    257                             response.end("内部错误,请联系管理员");
    258                         } else {
    259                             var contentType = config[ext] || "text/plain";
    260                             response.writeHead(200, {
    261                                 'Content-Type': contentType
    262                             });
    263                             response.write(file, "binary");
    264                             response.end();
    265                         }
    266                     });
    267                 }
    268             });
    269 
    270         }
    271 });
    272 server.listen(PORT);
    273 console.log("Server runing at port: " + PORT + ".");
    View Code

    config.js,用于配置。

     1 exports.types = {
     2   "css": "text/css",
     3   "gif": "image/gif",
     4   "html": "text/html",
     5   "htm": "text/html",
     6   "ico": "image/x-icon",
     7   "jpeg": "image/jpeg",
     8   "jpg": "image/jpeg",
     9   "js": "text/javascript",
    10   "json": "application/json",
    11   "pdf": "application/pdf",
    12   "png": "image/png",
    13   "svg": "image/svg+xml",
    14   "swf": "application/x-shockwave-flash",
    15   "tiff": "image/tiff",
    16   "txt": "text/plain",
    17   "wav": "audio/x-wav",
    18   "wma": "audio/x-ms-wma",
    19   "wmv": "video/x-ms-wmv",
    20   "xml": "text/xml"
    21 };
    22 
    23 exports.netServerUrlFlag = "NETSERVER";
    24 exports.netServerhost = "";
    25 exports.netServerport = "";
    26 
    27 exports.javaServerUrlFlag = "JAVASERVER";
    28 exports.javaServerhost = ""; //转发的地址
    29 exports.javaServerport = "";//转发的端口
    30 
    31 exports.fileServerUrlFlag="FileUpload";
    32 exports.webapp = "public";//项目目录
    33 
    34 exports.webport = "82";  //项目启动端口
    View Code

      

     
  • 相关阅读:
    利用 AlwaysInstallElevated 提权
    一批内网文章分享
    关于DLL劫持提权
    Xposed+JustTrustMe关闭ssl证书验证
    关于windows组策略首选项提权
    关于代替Procdump dump lsass的两种方法
    与ServletContext相关的监听器
    java EE 监听器
    ServletContext
    GenericServlet
  • 原文地址:https://www.cnblogs.com/shihaibin821/p/7683752.html
Copyright © 2020-2023  润新知