使用Gridfs-stream时gfs未定义 无法从MongoDB读取文件元数据
问题原因
你遇到的TypeError: Cannot read property 'files' of undefined报错有两个核心诱因:
- gfs初始化时序问题:
gfs是在数据库连接的open异步回调中完成赋值的,如果你在数据库连接未完成、gfs还处于初始的undefined状态时就调用GET接口,就会触发该报错;另外如果你的路由模块和gfs定义模块的导入/加载顺序错误,也会导致路由拿到的gfs始终是未赋值状态。 - 路由逻辑错误:
gfs.files.find返回的是查询游标,不是直接的文件对象,需要先调用.toArray()或者.next()才能拿到匹配的文件记录- 你在
find查询外直接调用了res.json(),相当于请求刚进入路由就直接返回了空响应,后续的文件流处理逻辑完全不会生效
修复步骤
1. 优化gfs初始化逻辑,添加存在性判断
可以直接在路由调用前先校验gfs是否初始化完成,也可以把gfs初始化封装成Promise确保加载完成后再挂载路由,最简修复方案如下:
// gfs定义部分保持不变,添加导出供路由使用 const conn = mongoose.createConnection(URI, {useNewUrlParser:true, useUnifiedTopology:true}); let gfs; Grid.mongo = mongoose.mongo; conn.once('open', () => { gfs = Grid(conn.db); gfs.collection('uploads'); console.log('GridFS初始化完成') }); const storage = new GridFsStorage({ url: URI, file: (req, file) => {...} }); const upload = multer({ storage }); // 导出gfs和upload module.exports = { gfs, upload }
2. 修正路由逻辑
// 首先从gfs定义的模块导入gfs const { gfs } = require('你的gfs定义文件路径') router.get('/image/:filename', (req, res) => { // 先判断gfs是否初始化完成 if(!gfs) { return res.status(503).send('服务未就绪,请稍后重试') } // 修正find查询逻辑,调用toArray拿到文件列表 gfs.files.find({filename: req.params.filename}).toArray(function(err, files) { if(err) { return res.status(500).send('查询失败') } // 判断文件是否存在 if(!files || files.length === 0) { return res.status(404).send("Image not found"); } const file = files[0] // 校验是图片类型再返回 if(file.contentType === 'image/jpeg' || file.contentType === 'image/png') { // 创建读取流管道返回,不需要额外拼接base64,pipe直接响应即可 const readStream = gfs.createReadStream(file.filename); readStream.on('error', () => { res.status(404).send("Image not found"); }) readStream.pipe(res); } else { res.status(400).send('请求的资源不是图片类型') } }) // 删掉原来外面的res.json(),不要提前返回响应 });
额外注意点
- 确保你的路由模块是在
gfs定义模块之后导入的,不要出现加载顺序倒置的情况 - 如果要返回base64格式的图片,需要在
end事件中再返回响应,不要提前返回:let data = ''; readStream.on('data', (chunk) => { data += chunk.toString('base64'); }) readStream.on('end', () => { res.json({ imageBase64: `data:${file.contentType};base64,${data}` }) })
内容的提问来源于stack exchange,提问作者forest
相关产品推荐
相关产品推荐

