nodejs实现文件上传

前言

随着前端的发展,本属于后端需要处理的一些功能模块也逐渐可以让前端实现。本篇大致记录一下文件上传功能。

一、上传文件

这里使用express+multer框架

const path = require('path')
const fs = require('fs')
const express = require('express');//4.18.2
const multer = require('multer');//1.4.5
// multer配置
// 详细配置
const storage = multer.diskStorage({
  // 指定上传文件的存储目录
  destination(req, file, callback) {
    let fpath = path.join(__dirname, '/dist/uploads/');//保存路径
    //判断文件夹
    fs.exists(fpath, (exists) => {
      if (exists) {//存在
        console.log('Directory exists!');
        callback(null, fpath);
      } else {//不存在,则创建文件夹,recursive选择true可以递归创建子文件夹
        fs.mkdir(fpath, { recursive: true }, (err) => {
              if (err) throw err;
              callback(null, fpath);
        });
        
      }
    });
    
  },
  // 指定上传文件的重命名,不写此函数,默认是md5加密,并且不会有拓展名的。
  filename(req, file, callback) {
    let dt = new Date();
    let fname =  Buffer.from(file.originalname, 'latin1').toString('utf-8');//这里是上传文件名有中文,需要转码
    fname = dt.getTime()+"-"+fname;
    callback(null, fname);
  },
});
const limits = {
    //限制文件大小50mb
    fileSize: 50 * 1024 * 1024,
    //限制文件数量
    files: 5
 }
let uploadTypeImgArr = ["bmp", "gif", "jpg", "jpeg", "png"]; 
const fileFilter = function(req, file, callback){
    //文件夹
    let index = req.originalUrl.lastIndexOf('/') + 1;
    let dname = req.originalUrl.substring(index);
        // 上传文件是音频还是图片
    let idx = dname.lastIndexOf('-')+1;
    let type = dname.substring(idx);
    //文件后缀
    let sufIndex = file.originalname.lastIndexOf('.')+1;
    let sufname = file.originalname.substring(sufIndex);
    //判断文件是否允许上传
    let typeFlag = false;
    if(type == 'img' && uploadTypeImgArr.includes(sufname)){
        typeFlag = true;
    }
    //console.log(type, sufname, typeFlag);
    if(typeFlag){
        req.fileCode = 200;
        req.fileMsg = "上传成功";
        callback(null, true);
    }else{
        req.fileCode = 500;
        req.fileMsg = "格式不正确";
        callback(null, false);
    }
}
const upload = multer({storage,limits,fileFilter});
//上传
/* 
  upload.single(fieldname)
    接受一个以 fieldname 命名的文件。这个文件的信息保存在 req.file
  upload.array(fieldname[, maxCount])
    接受一个以 fieldname 命名的文件数组。可以配置 maxCount 来限制上传的最大数量。这些文件的信息保存在 req.files。
  upload.fields(fields)
    接受指定 fields 的混合文件。这些文件的信息保存在 req.files。
    fields 应该是一个对象数组,应该具有 name 和可选的 maxCount 属性。
    eg:
    [
      { name: 'avatar', maxCount: 1 },
      { name: 'gallery', maxCount: 8 }
    ]
  upload.none()
    只接受文本域。如果任何文件上传到这个模式,将发生 "LIMIT_UNEXPECTED_FILE" 错误。这和 upload.fields([]) 的效果一样。
*/
app.post('/upload/:type', upload.single('file'), (req, res) => {
    let rt = new pojo.ResultData([req.fileCode, req.fileMsg, req.file]);
    res.send(rt)
})

二、一些问题

nodejs express multer 保存文件名为中文时乱码,问题解决 originalname,上面代码有具体位置

let fileOriginalName = Buffer.from(req.file.originalname, 'latin1').toString('utf-8');

上传时文件夹不存在的情况

//判断文件夹
    fs.exists(fpath, (exists) => {
      if (exists) {//存在
        console.log('Directory exists!');
        callback(null, fpath);
      } else {//不存在,则创建文件夹,recursive选择true可以递归创建子文件夹
        fs.mkdir(fpath, { recursive: true }, (err) => {
              if (err) throw err;
              callback(null, fpath);
        });
        
      }
    });

参考

https://www.nhooo.com/note/qa3ckq.html   
https://blog.csdn.net/yun_hou/article/details/97002993   
https://blog.csdn.net/KimBing/article/details/134341763   
https://blog.csdn.net/ccnever/article/details/130631117   
https://blog.csdn.net/weixin_68658847/article/details/128755739   
https://blog.csdn.net/qq_53109172/article/details/129210283  

posted @ 2024-01-26 18:45  Auler  阅读(413)  评论(0编辑  收藏  举报