使用Node.js+Express上传图片至MongoDB报错,求修正方案
问题分析与修复方案
核心错误原因
你遇到的 TypeError: Cannot read properties of undefined (reading 'buffer') 错误,主要是因为以下几个关键问题:
1. HTML 表单缺少文件上传必需的编码类型
表单提交文件时,必须指定 enctype="multipart/form-data",否则浏览器无法正确传递文件数据,导致 Multer 无法解析文件。
修复后的 HTML 代码:
<form action="/addWine" method="post" enctype="multipart/form-data"> <label for="">Name:</label> <textarea name="goods" id="" cols="10" rows="5"></textarea> <label for="">Quantity:</label> <input type="text" name="quantity"> <label for="">Price:</label> <input type="text" name="price"> <label for="">Photo:</label> <input type="file" name="photo"> <button type="submit">ADD WINE</button> </form>
2. 服务端代码的文件读取错误
- Multer 解析后的文件对象存储在
req.file中,而非req.body.file - 你当前使用的是磁盘存储模式(
dest: './uploads'),这种模式下 Multer 会将文件保存到磁盘,不会在req.file中提供buffer属性;若要直接获取文件缓冲区,需改用内存存储模式。
修复后的服务端代码:
const express = require('express') const { default: mongoose } = require('mongoose') const multer = require('multer') const bodyParser = require('body-parser') const Wine = require('./model/wine') // 使用内存存储模式,直接获取文件缓冲区 const storage = multer.memoryStorage() const upload = multer({ storage: storage }) app.post('/addWine', upload.single('photo'), async (req, res) => { try { const { goods, price, quantity } = req.body // 检查是否有文件上传 if (!req.file) { throw new Error('请上传图片') } const wine = new Wine({ goods, price, quantity, photo: { data: req.file.buffer, contentType: req.file.mimetype } }) await wine.save() res.redirect('/admin') } catch (error) { console.log(error) res.redirect('/addWine') } })
3. Mongoose Schema 定义错误
你当前的 Schema 中,photo 字段同时指定了 type:Buffer 和 contentType:String,这不符合 Mongoose 的语法规则。需要将图片数据和内容类型拆分为子字段或独立字段。
修复后的 Schema 代码:
const mongoose = require('mongoose'); const Schema = mongoose.Schema; const wineSchema = new Schema({ goods: { type: String, required: true }, quantity: { type: String, required: true }, price: { type: String, required: true }, photo: { data: { type: Buffer, required: true }, contentType: { type: String, required: true } } }) module.exports = mongoose.model('Wine', wineSchema)
额外注意事项
- 直接将图片缓冲区存储到 MongoDB 适合小体积图片,若处理大文件,建议使用云存储并存储文件 URL 到数据库,这样更高效。
- 记得处理文件上传的边界情况(如无文件上传、文件类型不符合要求等),提升代码健壮性。
内容的提问来源于stack exchange,提问作者Francis
相关产品推荐
相关产品推荐

