Angular响应式表单上传文件到Nest.js服务端file字段为空如何解决?
问题根因
使用JSON格式提交包含File对象的请求时,浏览器的JSON序列化逻辑无法处理二进制文件类型,会直接将File对象转为空对象{},因此后端收到的file字段为空。
修复方案
前端修改:将请求格式改为multipart/form-data
原有模态框的文件获取逻辑无需修改,仅调整AdService中的请求发送逻辑,改用FormData包装所有参数:
export class AdService { constructor(private readonly http: HttpClient) { } addAd(ad: InstaAdData): Observable<InstaAdData> { const formData = new FormData(); // 追加文件 formData.append('file', ad.file); // 追加普通文本字段 formData.append('name', ad.name); // 嵌套对象转为JSON字符串后再追加 formData.append('config', JSON.stringify(ad.config)); // 注意:不要手动指定Content-Type头,浏览器会自动为FormData生成带boundary的正确请求头,移除原有httpOptions中设置的application/json相关配置 return this.http.post<InstaAdData>(`${environment.serviceHost}/ads/ad`, formData); } }
后端修改:适配multipart/form-data请求解析
Nest.js默认仅解析application/json格式的请求,需要使用FileInterceptor拦截器解析文件上传请求:
- 先安装multer类型依赖(如果还未安装):
npm install -D @types/multer
- 调整接口逻辑:
import { Controller, Post, UseInterceptors, UploadedFile, Body } from '@nestjs/common'; import { FileInterceptor } from '@nestjs/platform-express'; @Controller('ads') export class AdsController { @Post('ad') // 拦截器第一个参数对应前端FormData中文件的字段名,此处为file @UseInterceptors(FileInterceptor('file', { // 可选配置:直接指定文件存储目录,不需要手动写文件落盘逻辑 dest: './uploaded-ads', // 可选配置:限制单文件最大10MB limits: { fileSize: 10 * 1024 * 1024 } })) async createAd( // 接收上传的文件 @UploadedFile() file: Express.Multer.File, // 接收普通字段 @Body() body: { name: string, config: string } ) { // 将序列化的config字段转回对象 const config = JSON.parse(body.config); // file.buffer为文件二进制内容,如果你没有配置dest自动存储,可手动将buffer写入文件系统 // 后续业务逻辑 } }
内容的提问来源于stack exchange,提问作者meDom
相关产品推荐
相关产品推荐

