Express.js使用Multer上传zip存MongoDB后下载损坏如何解决
问题根本原因
你遇到的问题核心是Mongoose Schema中存储文件buffer的字段类型配置错误,导致二进制Buffer入库时被自动序列化为base64字符串,从库中读取时拿到的是base64编码后的内容而非原始二进制Buffer:
- 11KB原始文件转base64后体积膨胀约33%,刚好符合你观察到的下载后14KB的体积变化
- 图片类资源对格式容错性更高,即使拿到base64编码的Buffer部分场景也能正常解析,而zip文件有严格的二进制头/尾校验,一旦编码错误就会直接报损坏
- 缓存中存的是入库前的原始Buffer对象,所以从缓存读取下载完全正常
修复方案
第一步:修正Mongoose Schema的字段定义
检查你的pluginSchema中file字段的配置,必须显式将存储二进制内容的buffer子字段指定为Buffer类型,示例配置:
const pluginSchema = new mongoose.Schema({ // 其他字段省略... file: { fieldname: String, originalname: String, encoding: String, mimetype: String, buffer: Buffer, // 这里必须显式指定为Buffer类型,不能省略或者设为String size: Number }, // logo、screenshots等其他存储二进制资源的字段里的buffer也要同步设为Buffer类型 })
第二步:兼容历史数据的可选处理
如果已有历史数据是按base64格式存储的,读取后可以手动解码转成原始Buffer,修改下载逻辑如下:
// 新增buffer类型判断与转码逻辑 let fileBuffer = plugin.file.buffer if (typeof fileBuffer === 'string') { fileBuffer = Buffer.from(fileBuffer, 'base64') } res.set({ "Content-Type": plugin.file.mimetype, "Content-Disposition": `attachment; filename=${plugin.file.originalname}` }) res.send(fileBuffer)
额外优化建议
如果后续需要存储的压缩包体积超过16MB,建议改用MongoDB的GridFS方案存储大文件,避免超出BSON单文档大小限制。
内容的提问来源于stack exchange,提问作者YTGS
相关产品推荐
相关产品推荐

