通过文件缓冲区上传文件至Google Cloud时格式异常问题咨询
问题原因与修复方案
核心问题排查
- 上传的缓冲区内容为空:你当前
storage.ts中直接将buffer赋值为空白字符串,完全没有从请求中读取实际的文件二进制内容,相当于上传的是空文本内容,自然下载下来是内容异常的txt文件。 - 未指定文件的Content-Type:Google Cloud Storage默认会将未指定MIME类型的文件识别为
text/plain,下载时就会默认当作txt文件处理,即使文件名带正确后缀也会出现格式异常。 - 异步逻辑存在漏洞:
file.save方法如果用回调写法就不会返回Promise,你外层加的await完全不生效,会导致还没等上传完成就返回成功响应,且上传的错误也无法被外层的try/catch捕获。
修复代码
1. 调整upload.ts逻辑
将回调写法改为Promise写法适配async/await,新增Content-Type配置项:
const upload = async (fileBuffer: Buffer, filePath: string, fileName: string, contentType?: string) => { const file = bucket.file(path.join(filePath, fileName)); // 传入配置项指定文件MIME类型,无传入值时默认识别为通用二进制流 await file.save(fileBuffer, { contentType: contentType || 'application/octet-stream' }); }
2. 调整storage.ts逻辑
从请求中读取真实的文件二进制内容,再调用上传方法:
imageSender: async(req: Request, res: Response) => { try { // 读取请求体中的二进制内容拼接为Buffer,若用form-data上传可直接用multer中间件解析更方便 const buffer = await new Promise<Buffer>((resolve, reject) => { const chunks: Buffer[] = []; req.on('data', chunk => chunks.push(chunk)); req.on('end', () => resolve(Buffer.concat(chunks))); req.on('error', reject); }); // 从请求头获取前端传入的正确文件类型,也可以自己根据文件后缀判断赋值 const contentType = req.get('Content-Type') || undefined; // 文件名必须带正确后缀,比如上传png就写file.png,不要省略后缀 await upload(buffer, "folder", "file.png", contentType); res.status(200).send("文件上传成功"); } catch (err) { console.log(err); res.status(500).send(httpError(500, "文件上传失败")); } },
额外注意
如果是前端用form-data格式传文件,建议直接引入multer中间件处理文件解析,不需要手动拼接Buffer,multer会直接把解析好的文件Buffer、MIME类型、文件名等信息放到req.file属性中,避免自己处理请求体出现错误。
内容的提问来源于stack exchange,提问作者tugs
相关产品推荐
相关产品推荐

