GridFS调用createReadStream报grid.mongo.ObjectID非构造函数错误求助
报错原因
- 你使用的
gridfs-stream依赖包已停止维护,仅适配MongoDB Node.js驱动v3及更早版本。当前你项目中安装的mongoose内置了v4+版本的MongoDB驱动,该版本驱动对ObjectId的导出命名做了调整:旧版本同时支持ObjectID(末尾D大写)和ObjectId(末尾d小写)两种导出名称,新版本仅保留ObjectId小写命名。gridfs-stream内部仍在读取大写D的ObjectID构造函数,因此触发类型错误。
解决方法
方案1:使用MongoDB原生GridFSBucket(推荐)
无需依赖gridfs-stream包,直接使用mongoose内置MongoDB驱动自带的GridFSBucket接口,稳定性更高,修改代码如下:
const mongoose = require('mongoose'); const { GridFSBucket } = require('mongodb'); const connect = mongoose.connection; let gfsBucket; connect.once('open', () => { // 初始化GridFS桶,指定和之前一致的avatars集合名 gfsBucket = new GridFSBucket(connect.db, { bucketName: 'avatars' }); }); router.get('/:filename', async (req, res) => { try { // 查询匹配的文件 const fileList = await gfsBucket.find({ filename: req.params.filename }).toArray(); if (!fileList.length) { return res.status(404).json({ message: 'Not Found' }); } // 创建读取流返回文件 const readStream = gfsBucket.openDownloadStreamByName(req.params.filename); readStream.pipe(res); } catch (err) { console.log(err); res.status(400).json({ message: 'Request Failed' }); } });
方案2:临时兼容gridfs-stream(不推荐,仅做应急修复)
如果不想调整现有代码结构,可以手动给mongoose.mongo挂载旧命名的ObjectID构造函数,修改Grid实例化部分代码即可:
connect.once('open', () => { // 手动兼容旧版本命名 mongoose.mongo.ObjectID = mongoose.mongo.ObjectId; gfs = new Grid(connect.db, mongoose.mongo); gfs.collection('avatars'); });
该方案仅为临时补丁,由于gridfs-stream已多年未更新,后续还可能出现其他兼容性问题,生产环境优先使用方案1。
内容的提问来源于stack exchange,提问作者Max Karrtopelka
相关产品推荐
相关产品推荐

