最近公司需要一些做基础服务以及一个APP的后台数据分析管理系统,
为了成为全栈工程师,自告奋勇的开启了Nodejs的开发后端。
现在有一个基础服务:file的上传和下载,关于为什么是基础服务?因为file的上传和下载与业务逻辑无关,不管什么业务逻辑都可能调用该接口,故称之为:基础服务。 还有:短信网关也属于基础服务。
声明:我的开发环境是:Express
闲话少叙,开启正文。平时后端的文件上传思路都是:前端——后端服务器——CDN服务器(存储文件的服务器)。其中前端到后端服务器使用的一般也就是http, 而后端服务器到CDN服务器,这里我们使用的是FTP传输。
关于Nodejs使用FTP协议上传CDN服务器,npm网站有很多第三方,这里我是用的是: basic-ftp
npm地址:https://www.npmjs.com/package/basic-ftp
为了本地测试上传文件,这里我们在自己的电脑上搭建FTP服务器(CDN服务器),
搭建FTP服务器传送门:https://jingyan.baidu.com/article/0bc808fc408fa91bd585b94f.html
至此我们的环境都搭建好了。 开始代码。
上传文件
前端到后端服务器:
//单一文件上传
function uploadSingleLogic(request, callback) {
//Creates a new incoming form.
let form = new formidable.IncomingForm();
//设置文件上传存放地址(需要自己设置)
// form.uploadDir = "./public/images/";
form.uploadDir = filePath.file_type + '/';
//保留文件后缀
form.keepExtensions = true;
//执行里面的回调函数的时候,表单已经全部接收完毕了。
form.parse(request, function(err, fields, files) {
var extname = path.extname(files.content.name);
//文件缓存路径
var oldpath = files.content.path;
//CDN服务器存储的文件路径
// 新文件路径(也就是设置成自己的CDN服务器路径,需要自己设置)
let newFilePath = formUtils.cndFilePath(request.query.fileType);
//在CDN服务器要存储的文件名(需要自己设置)
let newFileName = formUtils.cndFileName(request.query.fileType, request.query.version, extname);
//文件送服务器到CDN服务器
dataToCDN(oldpath, newFilePath, newFileName).then(function(isSuccess) {
callback(isSuccess);
});
});
}
上面是大致流程,首先获取表单,然后设置本地文件缓存路径,然后生成新的文件路径,注意这里是在CDN服务器的路径,比如说,上传的是图片,那么就可以是: ‘/image’,如果是视频,就可以是: ‘/media’;接下来就是生成新的文件名(在CDN服务器的文件名);最后将生成的本地服务器使用FTP协议上传到CDN服务器,注意:上传成功之后,一定要删除本地缓存文件。
接下来看下asyncToCDN方法:
//本地CDN 服务器(这个就是你配置的FTP站点信息)
config = {
host: '192.168.11.184',
port: 21,
user: 'anonymous',
password: 'anonymous@'
};
//单文件上传
async function asyncToCDN(toCDNFilePath, newFilePath, newFileName) {
const client = new ftp.Client();
try{
await client.connect(config.host, 21);
await client.login(config.user, config.password);
await client.useDefaultSettings();
//确保路径存在(也就是不存在该路径的话,就创建该路径)
await client.ensureDir( newFilePath);
await client.upload(fs.createReadStream(toCDNFilePath), newFilePath + "/" + newFileName);
client.close();
console.log("上传成功:" + newFilePath + "/" + newFileName);
return true;
} catch(e) {
console.log("上传错误:" + e.message);
client.close();
return false;
}
}
function dataToCDN(toCDNFilePath, newFilePath, newFileName, callback) {
//读入文件流
asyncToCDN(toCDNFilePath, newFilePath, newFileName).then(function(isSuccess) {
callback(isSuccess);
});
}
上述代码有一点需要注意的就是,dataToCDN的then方法了,具体可以查一下:nodejs中async的使用
至此,单文件上传就可以了,那么多文件呢? 其实很简单,在asyncToCDN方法内,添加for循环:
for(let index = 0; index < newFileNameArray.length; index ++) {
await client.upload(fs.createReadStream(toCDNFilePathArray[index]), rootFilePath + newFilePath + "/" + newFileNameArray[index]);
}
这里的newFileNameArray也就是路径数组了。
删除文件
删除文件就很简答了,直接传递一个路径,
//deleteFilePath也就是要删除的文件
async function asyncDeleteCDN(deleteFilePath) {
const client = new ftp.Client();
try{
await client.connect(config.host, 21);
await client.login(config.user, config.password);
await client.useDefaultSettings();
await client.remove(deleteFilePath, false);
client.close();
console.log("删除CDN文件成功:" + deleteFilePath);
return null;
} catch(e) {
console.log("删除CDN文件失败:" + e.message);
client.close();
return e.message;
}
}
选用这个框架的原因是,一直在更新…