form data 不再是通过 & 分隔数据,而是用 --------- + 一串数字做为 boundary 分隔符

因为不是 url 的方式了,自然也不用再做 url encode

form-data 需要指定 content type 为 multipart/form-data,然后指定 boundary 也就是分割线。

Untitled


Nest 解析 form data 使用 FilesInterceptor 的拦截器

用 @UseInterceptors 装饰器启用,然后通过 @UploadedFiles 来取

非文件的内容,同样是通过 @Body 来取

注(引入相关类型声明):npm i -D @types/multer

import { AnyFilesInterceptor } from '@nestjs/platform-express';
import { CreatePersonDto } from './dto/create-person.dto';

@Controller('api/person')
export class PersonController {
  @Post('file')
  @UseInterceptors(AnyFilesInterceptor({
      dest: 'uploads/'
  }))
  body2(@Body() createPersonDto: CreatePersonDto, @UploadedFiles() files: Array<Express.Multer.File>) {
    console.log(files);
    return `received: ${JSON.stringify(createPersonDto)}`
  }
}

前端代码使用 axios 发送 post 请求,指定 content type 为 multipart/form-data

<!DOCTYPE html>
<html lang="en">
<head>
    <script src="<https://unpkg.com/[email protected]/dist/axios.min.js>"></script>
</head>
<body>
    <input id="fileInput" type="file" multiple/>
    <script>
        const fileInput = document.querySelector('#fileInput');

        async function formData() {
            const data = new FormData();
            data.set('name','光');
            data.set('age', 20);
            data.set('file1', fileInput.files[0]);
            data.set('file2', fileInput.files[1]);

            const res = await axios.post('/api/person/file', data, {
                headers: { 'content-type': 'multipart/form-data' }
            });
            console.log(res);     
        }

        fileInput.onchange = formData;
    </script>
</body>
</html>