【问题标题】:Can't upload file to MongoDb无法将文件上传到 MongoDb
【发布时间】:2025-12-12 16:20:03
【问题描述】:

我正在尝试使用 multer 和 multer-grid-fs-storage 将 .zip 文件上传到 MongoDb Atlas。

它编译得很好,但是没有任何东西上传到我的集群。

我已尝试将文件保存到磁盘存储并直接发送到 MongoDB,但均无效。

我正在测试失眠症。请求状态为 200(正常),但没有上传任何内容。当我 console.log req.file 它说未定义,当我记录 req.body 它记录一个空对象(即 {})。

  • 这是我的 index.js 文件,需要并使用路由和数据库连接:
const db = require('./db/index.js')
db.on('error', console.error.bind(console, 'MongoDB connection error:'))

require('dotenv').config();
const app = express();


const userRouter = require('./routes/user-routes')
app.use('/api', userRouter)

const fileRouter = require('./routes/file-routes')
app.use('/file', fileRouter)
  • 这是我的文件控制器模块:
const db = require('../db/index.js')
const fs = require('fs');
const path = require('path');
const multer = require('multer');
const GridFsStorage = require('multer-gridfs-storage') 

const storage = new GridFsStorage({
    db: db,
    file: (req, file) => {
      return {
        filename: file.originalname
      }
    }
  });

// const storage = multer.diskStorage({
//   destination: (req, file, cb) => {
//     const uploadDir= path.join (__dirname, "..", "uploads", "zip" `${Date.now()}`)
//     // fs.mkdirSync(zip)
//     cd (null, uploadDir)
//   }, 
//   filename: (req, file, cb) => {
//     cb(null, file.originalname)
//   }
// })

  // sets file input to single file
const singleUpload = multer({ storage: storage }).single('file');

 const getFiles = (req, res) => {
    gfs.files.find({ filename: req.params.filename }).toArray((err, files) => {
      if(!files || files.length === 0){
        return res.status(404).json({
          message: "Could not find file"
        });
      }
      var readstream = gfs.createReadStream({
        filename: files[0].filename
      })
      res.set('Content-Type', files[0].contentType);
      return readstream.pipe(res);
    });
};

const postFiles = (req, res) => {
  res.send({ success: true });
  console.log(req.file)
};

module.exports = {
  storage, 
  singleUpload,
  getFiles, 
  postFiles,
  // getFiles2, 
  // deleteFiles
}
  • 这是我的路由器
const express = require('express')

const FileCtrl = require('../controllers/file-ctrl')

const router = express.Router()

router.get('/getFiles', FileCtrl.getFiles)
router.get('/getFiles2', FileCtrl.getFiles2)
router.post('/postFiles', FileCtrl.singleUpload, FileCtrl.postFiles)
router.post('/deleteFiles', FileCtrl.deleteFiles)

module.exports = router;
  • 这是我的 MongoDb 连接模块
const mongoose = require('mongoose')

mongoose
    .connect('mongodb+srv://Nancelot:Archer212@cluster0-3d7n6.gcp.mongodb.net/test?retryWrites=true&w=majority', { useNewUrlParser: true })
    .catch(e => {
        console.error('Connection error', e.message)
    })

const db = mongoose.connection

module.exports = db

注释掉的multer storage object是我也试过的磁盘存储。两者都没有工作

【问题讨论】:

    标签: node.js mongodb express multer multer-gridfs-storage


    【解决方案1】:

    我不确定,你这边可能有什么问题,它实际上对我有用。我在正文中发送一个 .csv 文件,带有一个“文件”键。 但我必须重写你的 get 函数,才能取回这些文件。

    const getFiles = (req, res) => {
        const gfs = new mongoose.mongo.GridFSBucket(mongoose.connections[0].db);
        gfs.find({}).toArray((err, files) => {
            if (!files || files.length === 0) {
                return res.status(404).json({
                    message: 'Could not find file',
                });
            }
            var readstream = gfs.openDownloadStream(files[0]._id);
            res.set('Content-Type', files[0].contentType);
            return readstream.pipe(res);
        });
    };
    

    ...我建议像这样等待 mongo 连接打开(这可能是个问题) app.js:

    const express = require('express');
    const db = require('./db/index.js');
    const mongoose = require('mongoose');
    db.on('error', console.error.bind(console, 'MongoDB connection error:'));
    
    require('dotenv').config();
    const app = express();
    const run = () =>
        app.listen(3000, () => {
            console.log(`Server running on http://localhost:3000/`);
        });
    
    const fileRouter = require('./routes/file-routes.js');
    app.use('/file', fileRouter);
    mongoose.connection.once('open', run);
    

    【讨论】: