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

Multer无法保存文件求助:Node.js+Express文件上传异常

Multer文件上传到images文件夹失败的排查与解决

我是Node.js和Express的初学者,最近开始使用Multer包处理文件上传,尝试将传入的图片文件保存到images文件夹时遇到问题,尽管已尝试解决,但未达到预期效果。

控制器代码

const path = require("path");

const express = require("express");
const bodyParser = require("body-parser");
const mongoose = require("mongoose");
const session = require("express-session");
const MongoDBStore = require("connect-mongodb-session")(session);
const csrf = require("csurf");
const flash = require("connect-flash");
const multer = require("multer");

const errorController = require("./controllers/error");
const User = require("./models/user");

const MONGODB_URI =
  "mongodb+srv://Priyansh16:MongoPass123@cluster0.s3m1ro1.mongodb.net/shop?retryWrites=true&w=majority";

const app = express();
const store = new MongoDBStore({
  uri: MONGODB_URI,
  collection: "sessions",
});
const csrfProtection = csrf();

// Config object for multer.
const fileStorage = multer.diskStorage({
  destination: (req, file, cb) => {
    cb(null, "images");
  },
  filename: (req, file, cb) => {
    cb(null, new Date().toISOString() + "-" + file.originalname);
  },
});

app.set("view engine", "ejs");
app.set("views", "views");

const adminRoutes = require("./routes/admin");
const shopRoutes = require("./routes/shop");
const authRoutes = require("./routes/auth");

app.use(bodyParser.urlencoded({ extended: false }));

// Multer Middleware
app.use(multer({ storage: fileStorage }).single("image"));

app.use(express.static(path.join(__dirname, "public")));
app.use(
  session({
    secret: "my secret",
    resave: false,
    saveUninitialized: false,
    store: store,
  })
);

// CSRF Middleware
app.use(csrfProtection);

// Flash Messages
app.use(flash());

app.use((req, res, next) => {
  if (!req.session.user) {
    return next();
  }
  User.findById(req.session.user._id)
    .then((user) => {
      if (!user) {
        return next();
      }
      req.user = user;
      next();
    })
    .catch((err) => {
      throw new Error(err);
    });
});

// Locals
app.use((req, res, next) => {
  res.locals.isAuthenticated = req.session.isLoggedIn;
  res.locals.csrfToken = req.csrfToken();
  next();
});

// Routes
app.use("/admin", adminRoutes);
app.use(shopRoutes);
app.use(authRoutes);

app.get("/500", errorController.get500);

app.use(errorController.get404);

app.use((error, req, res, next) => {
  res.redirect("/500");
});

mongoose
  .connect(MONGODB_URI)
  .then((result) => {
    app.listen(3000);
  })
  .catch((err) => {
    console.log(err);
  });

排查与解决步骤

  • 确认目标文件夹存在:Multer不会自动创建images文件夹,手动在项目根目录创建该文件夹,或者在Multer的destination回调中添加自动创建逻辑:

    const fs = require('fs');
    const fileStorage = multer.diskStorage({
      destination: (req, file, cb) => {
        const dir = 'images';
        if (!fs.existsSync(dir)) {
          fs.mkdirSync(dir, { recursive: true }); // recursive支持创建多级目录
        }
        cb(null, dir);
      },
      filename: (req, file, cb) => {
        cb(null, new Date().toISOString().replace(/:/g, '-') + "-" + file.originalname);
      },
    });
    
  • 修复文件名非法字符:new Date().toISOString()生成的字符串包含冒号(:),Windows系统禁止文件名包含该字符,需替换为合法字符(如横杠):new Date().toISOString().replace(/:/g, '-')

  • 检查表单属性:确保上传文件的表单设置了enctype="multipart/form-data",否则Multer无法解析文件数据。

  • 权限检查:如果是Linux/macOS系统,执行chmod 755 images赋予Node进程写入该文件夹的权限。

  • 添加错误捕获:修改Multer中间件,捕获上传过程中的错误以便排查:

    const upload = multer({ storage: fileStorage }).single("image");
    app.use((req, res, next) => {
      upload(req, res, (err) => {
        if (err) {
          console.error("上传错误:", err);
          return res.redirect('/500');
        }
        next();
      });
    });
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.30 23:17:10