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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 13:32:42