使用NestJS上传图片至Cloudinary时遇"buf"参数错误求助
NestJS 上传图片到 Cloudinary 报错解决
问题描述
使用NestJS将图片上传至Cloudinary时触发错误:
ERROR [RpcExceptionsHandler] "buf" argument must be a string or an instance of Buffer
TypeError: "buf" argument must be a string or an instance of Buffer
已确认file.buffer类型为Buffer,但上传仍失败,相关代码如下:
service.ts
import { Injectable } from '@nestjs/common'; import { UploadApiErrorResponse, UploadApiResponse, v2 } from 'cloudinary'; import toStream = require('buffer-to-stream'); @Injectable() export class CloudinaryService { async uploadImage(file: Express.Multer.File): Promise<UploadApiResponse | UploadApiErrorResponse> { return new Promise((resolve, reject) => { const upload = v2.uploader.upload_stream((error, result) => { if (error) return reject(error); resolve(result); }); toStream(file.buffer).pipe(upload); }); } }
module.ts
import { Module } from '@nestjs/common'; import { CloudinaryServiceController } from './cloudinary-service.controller'; import { CloudinaryService } from './cloudinary-service.service'; import { CloudinaryProvider } from './cloudinary-service.provider'; @Module({ imports: [], controllers: [CloudinaryServiceController], providers: [CloudinaryProvider, CloudinaryService], exports: [CloudinaryProvider, CloudinaryService], }) export class CloudinaryServiceModule {}
解决方案
1. 替换buffer-to-stream为原生Buffer流
buffer-to-stream可能存在版本兼容问题,改用Node.js原生Readable流处理:
import { Injectable } from '@nestjs/common'; import { UploadApiErrorResponse, UploadApiResponse, v2 } from 'cloudinary'; import { Readable } from 'stream'; @Injectable() export class CloudinaryService { async uploadImage(file: Express.Multer.File): Promise<UploadApiResponse | UploadApiErrorResponse> { return new Promise((resolve, reject) => { const upload = v2.uploader.upload_stream((error, result) => { if (error) return reject(error); resolve(result); }); Readable.from(file.buffer).pipe(upload); }); } }
2. 直接上传Base64格式
绕开流处理问题,将Buffer转为Base64字符串后上传:
import { Injectable } from '@nestjs/common'; import { UploadApiErrorResponse, UploadApiResponse, v2 } from 'cloudinary'; @Injectable() export class CloudinaryService { async uploadImage(file: Express.Multer.File): Promise<UploadApiResponse | UploadApiErrorResponse> { const base64Image = `data:${file.mimetype};base64,${file.buffer.toString('base64')}`; return v2.uploader.upload(base64Image, { resource_type: 'auto' }); } }
3. 校验Multer控制器配置
确保控制器中正确配置Multer,接收完整的Express.Multer.File对象:
import { Controller, Post, UploadedFile, UseInterceptors } from '@nestjs/common'; import { FileInterceptor } from '@nestjs/platform-express'; import { CloudinaryService } from './cloudinary-service.service'; @Controller('upload') export class CloudinaryServiceController { constructor(private readonly cloudinaryService: CloudinaryService) {} @Post() @UseInterceptors(FileInterceptor('image')) // 确保表单字段名与前端一致 async uploadFile(@UploadedFile() file: Express.Multer.File) { return this.cloudinaryService.uploadImage(file); } }
4. 更新Cloudinary依赖
确保cloudinary包为最新版本,执行命令:
npm update cloudinary
内容的提问来源于stack exchange,提问作者Antonio
相关产品推荐
相关产品推荐

