网络环境
- 系统有三个电脑:A和B在一个网段M,C单独在另一个网段N
- MN彼此不能访问,只有B能通过特殊方式访问C,反之不通
- AB可以双向访问
- A是前端服务器,BC都是后端服务器,安装有NodeJS+Express
技术需求
现在有这样的需求:
用户需要通过A给B发命令,让其传输B上的某个文件夹给C
分析问题
按照前面的描述,BC都是没有前端页面的,只有后台API服务,因此不能用常规的input
标签在前端上传,只能在代码里传文件到C去,同时C要写接收服务.传输的过程中还需要压缩以节约时间.
代码
后端的B需要安装几个库,其中adm-zip form-data multer
是核心的库
npm install express cors adm-zip form-data
首先是B,先创建一个接收A发来的启动传输命令.这里用了form-data
库,很方便的就可以直接上传
var express = require('express')
const admZip = require("adm-zip");
const fs = require('fs');
const FormData = require('form-data');
const path = require('path');
const cors = require('cors')
const bodyParser = require('body-parser')
const port = 8700
var app = express()
app.use(cors())
app.use(bodyParser.urlencoded({
extended: false
}));
app.use(bodyParser.json());
app.use(express.static('public'))
// 接收A传过来的启动传输命令,key是要传输的文件夹名称
app.get('/upload', (req, res) => {
let key = req.query.key
if(key === undefined || key === null)
return res.send({
code:201,
message:'错误'
})
let zipName = `${key}.zip`
let zipPath = `D:/Code/nodejs/send-file-test/${key}.zip`
let zip = new admZip();
// add local file 测试随便打包几个文件,没按Key来
zip.addLocalFile("D:/Code/nodejs/send-file-test/package.json");
zip.addLocalFile("D:/Code/nodejs/send-file-test/package-lock.json");
zip.writeZip(zipPath);
let check = setInterval(()=>{
if (fs.existsSync(zipPath))
{
clearInterval (check)
let form = new FormData();
form.append("file", fs.createReadStream(zipPath));
// 向C提交文件数据
form.submit('http://10.33.200.1:8700/api/upload', function(err, res2) {
res2.resume();
return res.send({
code:200,
message:'成功'
})
});
}
},1000)
})
app.listen(port, () => {
console.log(`服务运行中 http://localhost:${port}`)
})
后端的B需要安装几个库
npm install express cors adm-zip multer
然后是C端写接收服务,和接收普通POST服务一样,使用multer
库更加方便
var express = require('express')
var multer = require('multer')
var upload = multer({ dest: 'uploads/' })
const admZip = require("adm-zip");
const axios = require('axios');
const fs = require('fs');
const path = require('path');
const cors = require('cors')
const bodyParser = require('body-parser')
const port = 8700
var app = express()
app.use(cors())
app.use(bodyParser.urlencoded({
extended: false
}));
app.use(bodyParser.json());
app.use(express.static('public'))
app.post('/api/upload', upload.single('file'), function (req, res, next) {
const destName = path.join(req.file.destination,req.file.originalname)
const destPath = destName.substring(0,destName.length-4)
if(!fs.existsSync(destPath))
fs.mkdirSync(destPath);
fs.renameSync(req.file.path,destName)
const zip = new admZip( destName );
zip.extractAllTo(destPath, true);
fs.unlinkSync(destName)
return res.send({status:'done'})
})
app.listen(port, () => {
console.log(`服务运行中 http://localhost:${port}`)
})
各种运行服务后,在A端用postman
发起调用https://192.168.1.2:8700/upload?key=123456556