使用Multer Node.js上传图片至谷歌云的异常问题求助
解决Multer diskStorage上传谷歌云出现空文件的问题
我来帮你排查下问题:你现在遇到的空文件问题,核心原因是错误地把文件存储的目录路径(destination)传给了流的end()方法,而不是磁盘上实际的文件内容。当用diskStorage时,Multer会把文件写到本地磁盘,你需要读取这个文件的内容再上传到谷歌云。
修正后的代码示例
首先,我们需要引入fs模块来读取本地文件,然后正确传递文件内容给谷歌云的写入流:
const util = require('util'); const fs = require('fs'); const gc = require('../config/'); const bucket = gc.bucket('jsimage'); // bucket name const { format } = util; // 把fs.readFile转成Promise形式,方便异步操作 const readFile = util.promisify(fs.readFile); const uploadImage = (file) => new Promise(async (resolve, reject) => { console.log(file); const { filename, path: filePath } = file; // 这里用path,它是文件的完整本地路径 const blob = bucket.file(filename); const blobStream = blob.createWriteStream({ resumable: false }); try { // 读取本地磁盘上的文件内容 const fileContent = await readFile(filePath); blobStream.on('finish', () => { const publicUrl = format( `https://storage.googleapis.com/${bucket.name}/${blob.name}` ); // 可选:上传完成后删除本地临时文件,避免占用空间 fs.unlink(filePath, (err) => { if (err) console.error('删除本地临时文件失败:', err); }); resolve(publicUrl); }) .on('error', (err) => { reject(`上传图片失败: ${err.message}`); }) .end(fileContent); } catch (err) { reject(`读取本地文件失败: ${err.message}`); } }); module.exports = uploadImage;
关键说明
- 获取正确的文件路径:使用
file.path而不是destination,path是Multer存储文件的完整本地路径(包含文件名),而destination只是存储目录。 - 读取文件内容:通过
fs.readFile读取本地文件的二进制内容,再传给blobStream.end(),这样谷歌云才能拿到真实的图片数据。 - 可选:清理本地临时文件:上传完成后记得用
fs.unlink删除本地的临时文件,避免服务器磁盘被占满。 - 关于重命名文件:如果你需要自定义文件名,完全可以在Multer配置
diskStorage的时候就设置好,比如:
const storage = multer.diskStorage({ destination: function (req, file, cb) { cb(null, './tmp/uploads'); // 临时存储目录 }, filename: function (req, file, cb) { // 自定义文件名,比如用时间戳+原文件名后缀 const uniqueSuffix = Date.now() + '-' + Math.round(Math.random() * 1E9); cb(null, `image-${uniqueSuffix}.${file.originalname.split('.').pop()}`); } }); const upload = multer({ storage: storage });
这样既解决了重命名问题,又能正确把完整的图片内容上传到谷歌云啦。
内容的提问来源于stack exchange,提问作者yokana
相关产品推荐
相关产品推荐

