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

转发代码段:

 server {
listen 80;
server_name xxx.xxx.cn;
location ~* /eureka {
rewrite /eureka/(.*) /$1 break;
rewrite /eureka /$1 break;
proxy_pass http://172.16.49.229:8001;
}
location ~* /admin {
rewrite /admin/(.*) /$1 break;
rewrite /admin /$1 break;
proxy_pass http://172.16.49.229:8001;
}
location ~* /crm {
rewrite /crm/(.*) /$1 break;
rewrite /crm /$1 break;
proxy_pass http://172.16.49.229:8001;
}
location ~* /config-server {
rewrite /config-server/(.*) /$1 break;
rewrite /config-server /$1 break;
proxy_pass http://172.16.49.229:8001;
} }

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

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

   var body = '';
var req = http.request(opt, function (res) {
res.setEncoding('binary'); //二进制binary
res.on('data', function (data) {
body += data;
}).on('end', function () {
response.writeHead(200, res.headers);
response.write(body, "binary");
response.end();
});
}).on('error', function (e) {
response.end('内部错误,请联系管理员!MSG:' + e);
console.log("error: " + e.message);
})

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

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

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

2.刚开始没有转发文件的操作,就做的很简单,用户传过来啥就,拦截到,进行转发,一切都很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做中转服务器,转发接口的更多相关文章

  1. NodeJS做中转服务器,转发接口

    搬家后的博客地址:http://www.cnblogs.com/shihaibin821/p/7683752.html

  2. 深入浅出node.js游戏服务器开发1——基础架构与框架介绍

    2013年04月19日 14:09:37 MJiao 阅读数:4614   深入浅出node.js游戏服务器开发1——基础架构与框架介绍   游戏服务器概述 没开发过游戏的人会觉得游戏服务器是很神秘的 ...

  3. 【Node】node.js实现服务器的反向代理,解决跨域问题

    跨域对于前端来说是一个老大难的问题,许多方法如jsonp.document.domain + iframe...都有或多或少的问题,一个最佳实践就是通过服务器nginx做反向代理,但奈何不懂相关知识, ...

  4. WSGI——python web 服务器网关接口

    转载请注明原文地址:https://www.cnblogs.com/ygj0930/p/10826084.html 一:服务器.服务器软件.应用程序(后台) 我们常说“服务器”,实际上服务器是一个很宽 ...

  5. App开发:模拟服务器数据接口 - MockApi

    为了方便app开发过程中,不受服务器接口的限制,便于客户端功能的快速测试,可以在客户端实现一个模拟服务器数据接口的MockApi模块.本篇文章就尝试为使用gradle的android项目设计实现Moc ...

  6. 用http-server 创建node.js 静态服务器

    今天做一本书上的例子,结果代码不能正常运行,查询了一下,是语法过时了,书其实是新买的,出版不久. 过时代码如下 var connect=require('connect'); connect.crea ...

  7. mysql-proxy做客户端连接转发【外网访问内网mysql】

    功能 用于外网客户端连接内网的MySQL,将此工具安装在中转服务器上. 软件版本 mysql-proxy-0.8.1-linux-rhel5-x86-64bit.tar.gz 简单的配置过程 解压后有 ...

  8. tomcat用做图片服务器

    最近做了个小网站,就是用tinyce富文本编辑器,https://www.511easy.com/ 保持字体排版和图片 发现博客园的图片,一天之后就无法显示 就想着自己做一个图片服务器,上传图片到指定 ...

  9. Nginx做缓存服务器

    Nginx做缓存服务器 Nginx配置 1.主配置/etc/nginx/nginx.conf worker_processes 1; events { worker_connections 1024; ...

随机推荐

  1. MongoDB学习教程(2)-常用命令

    1.MongoDB 创建数据库 use DATABASE_NAME,如果数据库不存在,则创建数据库,否则切换到指定数据库. > use test_0902 switched to db test ...

  2. Access-Control-Allow-Origin与Ajax跨域

    问题 在某域名下使用Ajax向另一个域名下的页面请求数据,会遇到跨域问题.另一个域名必须在response中添加 Access-Control-Allow-Origin 的header,才能让前者成功 ...

  3. JVM性能调优,GC

    刚刚做完了一个项目的性能测试,“有幸”也遇到了内存泄露的案例,所以在此和大家分享一下. 主要从以下几部分来说明,关于内存和内存泄露.溢出的概念,区分内存泄露和内存溢出:内存的区域划分,了解GC回收机制 ...

  4. ASP.NET MVC 学习笔记 1

    1. 什么是ASP.Net MVC ASP.Net MVC是一种开发Web应用程序的工具(is a web application development framework),采用Model-Vie ...

  5. php代码常见错误详解整理

    错误类型: 一.未使用二进制上传   代码:    Fatal error: This encoded file is corrupted. Please refer to http://www.ze ...

  6. Zookeeper 笔记-应用场景

    应用场景:数据发布,订阅:分布式应用配置项:分布式计数器:统一命名服务:状态同步服务:集群管理:Master选举:分布式锁:定时任务争夺:分布式队列:分布式协调通知 特点:顺序一致性,原子性,单一视图 ...

  7. LeetCode 562. Longest Line of Consecutive One in Matrix(在矩阵中最长的连续1)$

    Given a 01 matrix M, find the longest line of consecutive one in the matrix. The line could be horiz ...

  8. LeetCode 59. Spiral Matrix II (螺旋矩阵之二)

    Given an integer n, generate a square matrix filled with elements from 1 to n2 in spiral order. For ...

  9. Hbuilder中添加Babel自动编译

    Hbuilder是一个不错的H5开发IDE. Babel是EMCAScript最新标准的编译器,很多ES的最新特性都可以在Babel中尝试. 如果可以有办法在Hbuilder中直接使用ES6,并通过B ...

  10. DB---数据库中Schema的理解

    今天看到了Schema一词,对于它的理解网上也是说法很多,有一种受到认可的程度比较大,暂且先使用一下: " 首先我来做一个比喻,什么是Database,什么是Schema,什么是Table, ...