MongoDB GridFS文件上传时_id属性未定义报错求助
问题描述
开发一款支持用户发布带图片文章的社交应用,采用MongoDB搭配GridFS存储图片,使用multer-gridfs-storage作为文件处理中间件。每次上传文件时服务器崩溃,提示gridfs.js文件中的_id属性未定义。已尝试修改MongoDB连接配置、排查GridFs.js文件,问题仍未解决。
以下是upload.js中间件代码:
const multer = require("multer"); const { GridFsStorage } = require("multer-gridfs-storage"); const MongoClient = require("mongodb").MongoClient; require("dotenv").config(); // const methodOverride = require("method-override"); const promise = MongoClient.connect(process.env.MONGO_URI).then((client) => client.db(process.env.DATABASE) ); const storage = new GridFsStorage({ // url: process.env.MONGO_URI, db: promise, options: { useNewUrlParser: true, useUnifiedTopology: true }, file: (req, file) => { console.log(file); const match = ["image/png", "image/jpeg", "image/jpg"]; // console.log(file); if (match.indexOf(file.mimetype) === -1) { return { bucketName: "files", filename: `${Date.now()}-posts-${file.originalname}` }; } return { bucketName: "photos", filename: `${Date.now()}-posts-${file.originalname}` }; } }); // const upload = multer({ storage }); // module.exports = upload; module.exports = multer({ storage }).fields([ { name: "image", maxCount: 1 }, // { name: "coverLetter", maxCount: 1 }, ]);
报错信息
id: f._id, ^ TypeError: Cannot read properties of undefined (reading '_id') at GridFSBucketWriteStream.emitFile (C:\Users\ariel\OneDrive\Desktop\react-native\project2\server\apis\node_modules\multer-gridfs-storage\lib\gridfs.js:306:31) at GridFSBucketWriteStream.emit (node:events:525:35) at finish (node:internal/streams/writable:748:10) at process.processTicksAndRejections (node:internal/process/task_queues:82:21)
解决方法
这个错误核心是multer-gridfs-storage没正确获取MongoDB数据库实例,导致后续操作读不到文件_id。推荐两种修复方式:
方式一:改用url参数直接连接数据库
放弃手动创建MongoClient连接,让中间件自行处理连接逻辑,这是最省心的方案:
const multer = require("multer"); const { GridFsStorage } = require("multer-gridfs-storage"); require("dotenv").config(); const storage = new GridFsStorage({ url: `${process.env.MONGO_URI}/${process.env.DATABASE}`, options: { useNewUrlParser: true, useUnifiedTopology: true }, file: (req, file) => { const match = ["image/png", "image/jpeg", "image/jpg"]; if (match.indexOf(file.mimetype) === -1) { return { bucketName: "files", filename: `${Date.now()}-posts-${file.originalname}` }; } return { bucketName: "photos", filename: `${Date.now()}-posts-${file.originalname}` }; } }); module.exports = multer({ storage }).fields([ { name: "image", maxCount: 1 }, ]);
方式二:确保数据库Promise正确解析
如果坚持手动管理连接,要保证传给db的是已解析完成的数据库实例,而非未完成的Promise:
const multer = require("multer"); const { GridFsStorage } = require("multer-gridfs-storage"); const MongoClient = require("mongodb").MongoClient; require("dotenv").config(); // 用立即执行函数获取已解析的数据库实例 const dbInstance = (async () => { const client = await MongoClient.connect(process.env.MONGO_URI, { useNewUrlParser: true, useUnifiedTopology: true }); return client.db(process.env.DATABASE); })(); const storage = new GridFsStorage({ db: dbInstance, file: (req, file) => { const match = ["image/png", "image/jpeg", "image/jpg"]; if (match.indexOf(file.mimetype) === -1) { return { bucketName: "files", filename: `${Date.now()}-posts-${file.originalname}` }; } return { bucketName: "photos", filename: `${Date.now()}-posts-${file.originalname}` }; } }); module.exports = multer({ storage }).fields([ { name: "image", maxCount: 1 }, ]);
关键说明
原代码直接把MongoClient.connect().then(...)的Promise传给db参数,中间件处理时可能出现Promise解析时机不匹配的问题,导致拿不到有效数据库实例。用url配置能避开这类手动连接的潜在问题。
内容的提问来源于stack exchange,提问作者Somdev Behera
相关产品推荐
相关产品推荐

