NestJS上传文件至Azure Blob存储报ERR_INVALID_ARG_TYPE错误
问题根因
报错是因为传入blockblob.uploadData()的参数为undefined,你的代码存在两个核心问题:
- Multer默认使用磁盘存储模式,解析到的上传文件会写入本地临时目录,此时
file对象上不存在buffer属性,你直接读取file.buffer拿到的值就是undefined,不符合uploadData方法的参数类型要求。 - 你当前写的controller方法没有调用service层实现的
FileUpload逻辑,接口拿到文件后直接返回了file对象,根本不会执行Blob上传流程。 - 额外隐患:直接使用
file.originalname作为Blob文件名,容易出现同名文件覆盖、特殊字符不兼容的问题。
修复步骤
- 配置Multer使用内存存储
内存存储模式下,上传文件会以Buffer格式暂存在内存中,直接挂载到file.buffer属性,适配uploadData的传参要求。直接修改controller中FileInterceptor的配置即可:
import multer from 'multer'; // 其余import保持不变 @Post("uploadfile") // 给FileInterceptor传入内存存储配置,注意字段名"Server"必须和前端上传的表单字段名完全一致 @UseInterceptors(FileInterceptor("Server", { storage: multer.memoryStorage() })) async uploadFile(@UploadedFile() file: Express.Multer.File) { if (!file) { throw new Error("未接收到上传文件,请检查前端上传字段名是否为Server"); } // 调用service层的上传方法,不要直接return file return await this.blobService.FileUpload(file); }
注意:需要提前初始化你的BlobService实例,替换示例中this.blobService为你项目中实际的service实例化方式。
- 优化service层逻辑(可选但推荐)
增加参数校验、Blob类型配置、唯一文件名处理,避免潜在问题:
getblob(filename: string): BlockBlobClient { const connectionString = process.env.CONNECTION_STRING, containerName = process.env.BLOB_CONTAINER; if (!connectionString || !containerName) { throw new Error("Blob存储连接配置缺失,请检查环境变量"); } const blobServiceClient = BlobServiceClient.fromConnectionString(connectionString); const blobContainer = blobServiceClient.getContainerClient(containerName); return blobContainer.getBlockBlobClient(filename); } async FileUpload(file: Express.Multer.File) { if (!file?.buffer) { throw new Error("文件内容解析失败,请检查Multer配置"); } try { // 生成唯一文件名,避免同名文件覆盖,不需要可直接用file.originalname const fileSuffix = file.originalname.split(".").pop(); const uploadFileName = `${Date.now()}_${Math.random().toString(36).slice(2)}.${fileSuffix}`; const blockblob = this.getblob(uploadFileName); // 上传时设置正确的Content-Type,避免文件下载时类型异常 return await blockblob.uploadData(file.buffer, { blobHTTPHeaders: { blobContentType: file.mimetype } }); } catch (err) { console.log("Blob上传失败:", err); throw err; } }
验证注意点
- 确保存储账号连接字符串、容器名称配置正确,目标容器已经提前在Azure存储账号中创建。
- 前端上传文件时使用
multipart/form-data格式,字段名必须和后端配置的Server完全一致,否则后端无法解析到file对象。 - 内存存储适合100MB以下的小文件上传,如果是大文件建议改用分片上传逻辑,避免内存占用过高。
内容的提问来源于stack exchange,提问作者Binni kumari
相关产品推荐
相关产品推荐

