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

Node.js使用Multer上传图片报错:TypeError: 无法读取undefined的'image'属性

Node.js(Express+Multer+Mongoose)图片上传错误修正与原因分析

我编写的Node.js结合Express、Multer、Mongoose实现图片上传功能时,出现错误:TypeError: Cannot read properties of undefined(reading 'image'),以下是问题代码、错误原因及修正方案。

原代码

import bodyParser from "body-parser";
import express from "express";
import mongoose from "mongoose";
import ejs from "ejs";
import multer from "multer";

const app = express();
const port = 3000;

app.set("view engine", "ejs");
app.use(bodyParser.urlencoded({ extended: true }));
app.use(express.json());
app.use(express.static("public"));

// Image Upload

// Configure Multer
const storage = multer.diskStorage({
    destination: (req, file, cb) => {
        cb(null, "./uploads");
    },
    filename: (req, file, cb) => {
        cb(null, file.fieldname + "_" + Date.now + "_" + file.originalname);
    },
});

const upload = multer({
    storage,
});

// Connect to MongoDB database

mongoose.connect("mongodb://127.0.0.1:27017/restaurantDB")
    .then(() => {
        console.log("Database Created Succesfuly");
    })
    .catch((err) => {
        comsole.log(err);
    });

const productSchema = new mongoose.Schema({
    _id: {
        type: Number,
        required: true,
    },
    name: {
        type: String,
        required: true,
    },
    description: {
        type: String,
        required: true,
    },
    price: {
        type: Number,
        required: true
    },
    type: {
        type: String,
        required: true
    },
    imagePath: {
        type: String,
        required: true
    }
});

const Product = mongoose.model("Product", productSchema);

app.get("/", (req, res) => {
    res.render("index.ejs");
});
app.get("/about", (req, res) => {
    res.render("about.ejs");
});

app.get("/contact", (req, res) => {
    res.render("contact.ejs");
});
app.get("/pizza", (req, res) => {
    res.render("pizza.ejs");
});
app.get("/burgur", (req, res) => {
    res.render("burgur.ejs");
});
app.get("/beverage", (req, res) => {
    res.render("beverage.ejs");
});
app.get("/addproduct", (req, res) => {
    res.render("addproduct.ejs");
});

app.get("/product", (req, res) => {
    res.render("product.ejs");
});

app.post("/addproduct", upload.single("image"), (req, res) => {
    const id = req.body["id"];
    const name = req.body["name"];
    const description = req.body["description"];
    const price = req.body["price"];
    const type = req.body["type"];
    const file = req.file;

    if (!file) {
        // Handle the file upload error
        return res.status(400).send("File upload failed");
    }

    const product = new Product({
        _id: id,
        name: name,
        description: description,
        price: price,
        type: type,
        imagePath: `/uploads/${file.originalname}`
    });

    product.save();
    res.redirect("/product")

});

app.listen(port, () => {
    console.log(`Server is running on port ${port}`);
});

错误原因分析

  • Date.now未调用,应使用Date.now(),否则会将函数体作为字符串拼接,导致文件名异常
  • Mongoose连接错误处理中comsole.log拼写错误,应为console.log
  • 前端表单未设置enctype="multipart/form-data",导致Multer无法解析文件,req.file为undefined,进而引发读取image相关属性的错误
  • 未确保uploads目录存在,Multer不会自动创建该目录
  • imagePath使用file.originalname易导致文件名重复,应使用Multer生成的file.filename

修正后的代码

import bodyParser from "body-parser";
import express from "express";
import mongoose from "mongoose";
import ejs from "ejs";
import multer from "multer";
import fs from 'fs';
import path from 'path';

const app = express();
const port = 3000;
const uploadsDir = path.join(__dirname, './uploads');

// 确保uploads目录存在
if (!fs.existsSync(uploadsDir)) {
    fs.mkdirSync(uploadsDir);
}

app.set("view engine", "ejs");
app.use(bodyParser.urlencoded({ extended: true }));
app.use(express.json());
app.use(express.static("public"));
// 让uploads目录可访问
app.use('/uploads', express.static(uploadsDir));

// Configure Multer
const storage = multer.diskStorage({
    destination: (req, file, cb) => {
        cb(null, uploadsDir);
    },
    filename: (req, file, cb) => {
        // 调用Date.now()获取时间戳
        cb(null, file.fieldname + "_" + Date.now() + "_" + file.originalname);
    },
});

const upload = multer({
    storage,
});

// Connect to MongoDB database
mongoose.connect("mongodb://127.0.0.1:27017/restaurantDB")
    .then(() => {
        console.log("Database Connected Successfully");
    })
    .catch((err) => {
        // 修正拼写错误
        console.log(err);
    });

const productSchema = new mongoose.Schema({
    _id: {
        type: Number,
        required: true,
    },
    name: {
        type: String,
        required: true,
    },
    description: {
        type: String,
        required: true,
    },
    price: {
        type: Number,
        required: true
    },
    type: {
        type: String,
        required: true
    },
    imagePath: {
        type: String,
        required: true
    }
});

const Product = mongoose.model("Product", productSchema);

// 路由部分保持不变
app.get("/", (req, res) => {
    res.render("index.ejs");
});
app.get("/about", (req, res) => {
    res.render("about.ejs");
});

app.get("/contact", (req, res) => {
    res.render("contact.ejs");
});
app.get("/pizza", (req, res) => {
    res.render("pizza.ejs");
});
app.get("/burgur", (req, res) => {
    res.render("burgur.ejs");
});
app.get("/beverage", (req, res) => {
    res.render("beverage.ejs");
});
app.get("/addproduct", (req, res) => {
    res.render("addproduct.ejs");
});

app.get("/product", (req, res) => {
    res.render("product.ejs");
});

app.post("/addproduct", upload.single("image"), async (req, res) => {
    const id = req.body["id"];
    const name = req.body["name"];
    const description = req.body["description"];
    const price = req.body["price"];
    const type = req.body["type"];
    const file = req.file;

    if (!file) {
        return res.status(400).send("请选择要上传的图片");
    }

    try {
        const product = new Product({
            _id: id,
            name: name,
            description: description,
            price: price,
            type: type,
            // 使用multer生成的文件名
            imagePath: `/uploads/${file.filename}`
        });
        await product.save();
        res.redirect("/product");
    } catch (err) {
        res.status(500).send("保存产品失败:" + err.message);
    }
});

app.listen(port, () => {
    console.log(`Server is running on port ${port}`);
});

额外说明

前端表单必须设置enctype="multipart/form-data",示例代码如下:

<form action="/addproduct" method="post" enctype="multipart/form-data">
    <input type="file" name="image" />
    <!-- 其他表单字段 -->
</form>

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.08 05:35:55