使用mongoose、gridfs-stream开发时报grid.mongo.GridStore is not a constructor错误求助
问题根因
TypeError: grid.mongo.GridStore is not a constructor错误源于你使用的gridfs-stream依赖包已停止维护,完全不兼容MongoDB Node.js驱动4.0及以上版本。而Mongoose 6.x/7.x默认内置了4.x以上的MongoDB驱动,官方已经彻底移除了早已废弃的GridStore类,因此调用时会触发该报错。
解决方案(推荐)
直接使用MongoDB原生的GridFSBucket替代gridfs-stream,无需依赖第三方未维护包,修改步骤如下:
- 移除
gridfs-stream相关的引入和初始化代码,在头部新增MongoDB原生GridFSBucket引入:
// 删掉 const Grid = require('gridfs-stream'); 这行 // 新增下面这行 const { GridFSBucket } = require('mongodb');
- 替换原有gfs初始化逻辑:
// 原有逻辑删掉 // let gfs; // connection.once('open', () => { // gfs = Grid(connection.db, mongoose.mongo); // gfs.collection('uploads'); // }); // 替换为以下逻辑 let gridFSBucket; connection.once('open', () => { gridFSBucket = new GridFSBucket(connection.db, { bucketName: 'uploads' }); });
- 修改文件读取逻辑,替换
createReadStream调用:
以你贴出的/image/:filename路由为例,修改如下(同时修复你原有代码中注释掉else分支导致的二次响应报错问题):
app.get('/image/:filename', (req, res) => { gfs.files.findOne({ _id: mongoose.Types.ObjectId(req.params.filename) }, (err, file) => { if (!file || file.length === 0) { console.log("not found") return res.status(404).json({ err: 'No file exists' }); } if (file.contentType === 'image/jpeg' || file.contentType === 'image/png') { console.log(file) // 替换原有createReadStream调用 const readStream = gridFSBucket.openDownloadStream(mongoose.Types.ObjectId(req.params.filename)) readStream.on('error', err => { console.log(err); return res.status(500).json({err: '读取文件失败'}) }); readStream.pipe(res); } else { // 原代码注释掉了else分支,会导致响应发送后还调用404接口产生二次报错,必须补上else分支 res.status(404).json({ err: 'Not an image' }); } }); });
- 检查你的
/api/files/delete接口逻辑,如果也用到了gridfs-stream的相关方法,一并替换为GridFSBucket的对应方法即可。
备选方案(不推荐长期使用)
如果你不想修改现有代码,可以降级Mongoose到5.x版本,该版本内置的MongoDB驱动还保留了GridStore类:
npm install mongoose@5.13.20
内容的提问来源于stack exchange,提问作者Anand
相关产品推荐
相关产品推荐

