直接用 form 表单提交数据就是这种

它和 query 字符串的方式的区别只是放在了 body 里

然后指定下 content-type 是 application/x-www-form-urlencoded

因为内容也是 query 字符串,所以也要用 encodeURIComponent 的 api 或者 query-string 库处理下

get 是把数据拼成 query 字符串放在 url 后面,于是表单的 post 提交方式的时候就直接用相同的方式把数据放在了 body 里

<aside> 💡 通过 & 分隔的 form-urlencoded 的方式需要对内容做 url encode,如果传递大量的数据,比如上传文件的时候就不是很合适了,因为文件 encode 一遍的话太慢了,这时候就可以用 form-data。

</aside>

用 Nest 接收的话,使用 @Body 装饰器,Nest 会解析请求体,然后注入到 dto 中

dto 是 data transfer object,就是用于封装传输的数据的对象

export class CreatePersonDto {
    name: string;
    age: number;
}
import { CreatePersonDto } from './dto/create-person.dto';

@Controller('api/person')
export class PersonController {
  @Post()
  body(@Body() createPersonDto: CreatePersonDto) {
    return `received: ${JSON.stringify(createPersonDto)}`
  }
}

前端代码使用 post 方式请求,指定 content type 为 application/x-www-form-urlencoded,用 qs 做下 url encode:

<!DOCTYPE html>
<html lang="en">
<head>
    <script src="<https://unpkg.com/[email protected]/dist/axios.min.js>"></script>
    <script src="<https://unpkg.com/[email protected]/dist/qs.js>"></script>
</head>
<body>
    <script>
        async function formUrlEncoded() {
            const res = await axios.post('/api/person', Qs.stringify({
                name: '光',
                age: 20
            }), {
                headers: { 'content-type': 'application/x-www-form-urlencoded' }
            });
            console.log(res);  
        }

        formUrlEncoded();
    </script>
</body>
</html>