NodeJs后端实现文件上传和下载

最近公司需要一些做基础服务以及一个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;
  }
}

选用这个框架的原因是,一直在更新…

猜你喜欢

转载自blog.csdn.net/lmq121210/article/details/84876304