首页 web前端 js教程 Node做中转服务器转发接口实例分享

Node做中转服务器转发接口实例分享

Jan 09, 2018 pm 01:48 PM
node 接口 服务器

本文主要介绍了Node做中转服务器转发接口的相关资料,需要的朋友可以参考下,希望能帮助到大家。

由于项目在做前后端分离,牵扯跨域和夸协议问题,临时抱佛脚,选择用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 Inspector 代理实现实例教程

node模块与npm包管理工具分析

Nodejs中crypto模块的安全知识分享

以上是Node做中转服务器转发接口实例分享的详细内容。更多信息请关注PHP中文网其他相关文章!

本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

AI Hentai Generator

AI Hentai Generator

免费生成ai无尽的。

热门文章

R.E.P.O.能量晶体解释及其做什么(黄色晶体)
3 周前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳图形设置
3 周前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.如果您听不到任何人,如何修复音频
3 周前 By 尊渡假赌尊渡假赌尊渡假赌
WWE 2K25:如何解锁Myrise中的所有内容
3 周前 By 尊渡假赌尊渡假赌尊渡假赌

热工具

记事本++7.3.1

记事本++7.3.1

好用且免费的代码编辑器

SublimeText3汉化版

SublimeText3汉化版

中文版,非常好用

禅工作室 13.0.1

禅工作室 13.0.1

功能强大的PHP集成开发环境

Dreamweaver CS6

Dreamweaver CS6

视觉化网页开发工具

SublimeText3 Mac版

SublimeText3 Mac版

神级代码编辑软件(SublimeText3)

如何将Dnsmasq配置为DHCP中继服务器 如何将Dnsmasq配置为DHCP中继服务器 Mar 21, 2024 am 08:50 AM

DHCP中继的作用是将接收到的DHCP数据包转发到网络上的另一个DHCP服务器,即使这两个服务器位于不同的子网中。通过使用DHCP中继,您可以实现在网络中心部署一个集中式的DHCP服务器,并利用它为所有网络子网/VLAN动态分配IP地址。Dnsmasq是一种常用的DNS和DHCP协议服务器,可以配置为DHCP中继服务器,以帮助管理网络中的动态主机配置。在本文中,我们将向您展示如何将dnsmasq配置为DHCP中继服务器。内容主题:网络拓扑在DHCP中继上配置静态IP地址集中式DHCP服务器上的D

用PHP构建IP代理服务器的最佳实践指南 用PHP构建IP代理服务器的最佳实践指南 Mar 11, 2024 am 08:36 AM

在网络数据传输中,IP代理服务器扮演着重要的角色,能够帮助用户隐藏真实IP地址,保护隐私、提升访问速度等。在本篇文章中,将介绍如何用PHP构建IP代理服务器的最佳实践指南,并提供具体的代码示例。什么是IP代理服务器?IP代理服务器是一种位于用户与目标服务器之间的中间服务器,它充当用户与目标服务器之间的中转站,将用户的请求和响应进行转发。通过使用IP代理服务器

电脑主板内部接口都有什么 推荐电脑主板内部接口介绍 电脑主板内部接口都有什么 推荐电脑主板内部接口介绍 Mar 12, 2024 pm 04:34 PM

我们在电脑组装的过程中,安装过程虽然简单,不过往往都是在接线上遇到问题,经常有装机用户误将CPU散热器的供电线插到了SYS_FAN上,虽然风扇可以转动,不过在开机可能会有F1报错“CPUFanError”,同时也导致了CPU散热器无法智能调速。下面装机之家分享一下电脑主板上CPU_FAN、SYS_FAN、CHA_FAN、CPU_OPT接口知识科普。电脑主板上CPU_FAN、SYS_FAN、CHA_FAN、CPU_OPT接口知识科普1、CPU_FANCPU_FAN是CPU散热器专用接口,12V工作

Go语言中常见的编程范式和设计模式 Go语言中常见的编程范式和设计模式 Mar 04, 2024 pm 06:06 PM

Go语言作为一门现代化的、高效的编程语言,拥有丰富的编程范式和设计模式可以帮助开发者编写高质量、可维护的代码。本文将介绍Go语言中常见的编程范式和设计模式,并提供具体的代码示例。1.面向对象编程在Go语言中,可以使用结构体和方法实现面向对象编程。通过定义结构体和给结构体绑定方法,可以实现数据封装和行为绑定在一起的面向对象特性。packagemaini

epic服务器离线进不了游戏怎么办?epic离线进不了游戏解决方法 epic服务器离线进不了游戏怎么办?epic离线进不了游戏解决方法 Mar 13, 2024 pm 04:40 PM

  epic服务器离线进不了游戏怎么办?这个问题想必很多小伙伴都有遇到过,出现了此提示就是导致正版的游戏无法启动,那么出现这个问题一般是网络和安全软件干扰导致的,那么应该怎么解决呢,本期小编就来和大伙分享解决方法,希望今日的软件教程可以帮助各位解决问题。  epic服务器离线进不了游戏怎么办:  1、很可能是被安全软件干扰了,将游戏平台和安全软件关闭在重启。  2、其次就是网络波动过大,尝试重启一次路由器,看看是否有效,如果条件可以的话,可以尝试使用5g移动网络来进行操作。  3、然后有可能是更

Pi Node教学:什么是Pi节点?如何安装和设定Pi Node? Pi Node教学:什么是Pi节点?如何安装和设定Pi Node? Mar 05, 2025 pm 05:57 PM

PiNetwork节点详解及安装指南本文将详细介绍PiNetwork生态系统中的关键角色——Pi节点,并提供安装和配置的完整步骤。Pi节点在PiNetwork区块链测试网推出后,成为众多先锋积极参与测试的重要环节,为即将到来的主网发布做准备。如果您还不了解PiNetwork,请参考Pi币是什么?上市价格多少?Pi用途、挖矿及安全性分析。什么是PiNetwork?PiNetwork项目始于2019年,拥有其专属加密货币Pi币。该项目旨在创建一个人人可参与

如何在服务器上安装 PHP FFmpeg 扩展? 如何在服务器上安装 PHP FFmpeg 扩展? Mar 28, 2024 pm 02:39 PM

如何在服务器上安装PHPFFmpeg扩展?在服务器上安装PHPFFmpeg扩展可以帮助我们在PHP项目中处理音视频文件,实现音视频文件的编解码、剪辑、处理等功能。本文将介绍如何在服务器上安装PHPFFmpeg扩展,以及具体的代码示例。首先,我们需要确保服务器上已经安装了PHP以及FFmpeg。如果没有安装FFmpeg,可以按照以下步骤安装FFmpe

PHP接口简介及其定义方式 PHP接口简介及其定义方式 Mar 23, 2024 am 09:00 AM

PHP接口简介及其定义方式PHP是一种广泛应用于Web开发的开源脚本语言,具有灵活、简单、强大等特点。在PHP中,接口(interface)是一种定义多个类之间公共方法的工具,实现了多态性,让代码更加灵活和可重用。本文将介绍PHP接口的概念及其定义方式,同时提供具体的代码示例展示其用法。1.PHP接口概念接口在面向对象编程中扮演着重要的角色,定义了类应

See all articles