You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Multer上传图片时自定义创建目录后文件无法保存问题求助

问题根源
  • 异步执行顺序错误:destination 配置中的 fs.access 及目录创建逻辑为异步操作,你未等待目录创建完成就直接调用了存储路径回调,Multer 执行文件写入时对应目录还未生成,导致文件写入失败。同时你将 async 关键字写在了 fs.access 的回调函数中,外层逻辑并不会等待该异步任务执行完成。
  • 冗余的目录校验逻辑:fs.promises.mkdir 开启 recursive: true 配置后会自动兼容已存在的目录,不需要提前通过 fs.access 判断目录是否存在,反而增加了异步逻辑复杂度。
修复方案

直接重写 destination 逻辑,等待目录创建完成后再调用回调返回存储路径即可,修复后的完整代码如下:

const storage = multer.diskStorage({
    destination: async function(request, file, callback) {  
        let userUploadDir = uploadDir + '/' + request.body.user + '/' + request.body.address;
        try {
            // 直接创建目录,recursive配置自动兼容已存在目录
            await fs.promises.mkdir(userUploadDir, { recursive: true });
            // 目录创建完成后再返回路径
            callback(null, userUploadDir);
        } catch (err) {
            callback(err);
        }
    },

    filename: function(request, file, callback) {
        let date = new Date();
        // 原代码getMonth()返回值从0开始,此处+1修正月份显示
        let stringDate = date.getFullYear() + "-" + (date.getMonth() + 1) + "-" + date.getDate() + "-" + date.getHours() + "-" + date.getMinutes();
        let newFileName = stringDate + "-" +  file.originalname;
        callback(null, newFileName);
    },

    fileFilter: function(request, file, callback) {
        let ext = path.extname(file.originalname).toLowerCase();
        // 增加toLowerCase兼容大写后缀的图片,比如.PNG
        if (ext !== ".png" && ext !== ".jpg" && ext !== ".jpeg" && ext !== ".webp") {
            return callback(new Error("Only images are allowed"));
        }
        callback(null, true);
    }
});

const upload = multer({
    storage: storage,
    limits: {
        fileSize: 1024 * 1024 * 5
    }
});

router.post("/image", upload.fields([{ name: 'file', maxCount: 3 }]), async (request, response, next) => {
     response.json({
         "message":"Successful file uploaded."
     })
})
额外注意事项
  • 前端提交 FormData 时,请保证 user、address 普通字段的添加顺序在 file 文件字段之前,Multer 按表单字段顺序解析,若文件字段在前,解析到文件时 request.body 还未拿到普通字段值,会导致目录生成错误。
  • 可根据自身需求决定是否保留月份修正、大小写后缀兼容的调整。

内容的提问来源于stack exchange,提问作者Nextrati

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.27 21:24:03