最近在学习神光大神的《Nest通关秘籍》,该小册主要包含下面这些内容:
现在购买还有优惠,《传送门》
接下来的日子里,我将更新一系列的学习笔记。感兴趣的可以关注我的专栏《Nest 通关秘籍》学习总结。
特别申明:本系列文章已经经过作者本人的允许。 大家也不要想着白嫖,我的笔记只是个人边学习边记录的,不是很完整,大家想要深入学习还是要自己去购买原版小册。
本节课我们来学习五种数据HTTP数据传输方式:
- url param
- query
- form-urlencoded
- form-data
- json
准备:测试项目
前置条件:使用
nest new project-name
生成一个nest项目。
使用nest g gernrate person
创建一个person
模块.
访问:http://localhost:3000/person/1, 我这里使用的apifox进行测试的:
如果你的也跟图中一样的,这就证明我们的api 接口跑通了。
再支持下静态资源的访问:调用下 useStaticAssets
来支持静态资源的请求:
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
import { NestExpressApplication } from '@nestjs/platform-express';
import { join } from 'path';
async function bootstrap() {
const app = await NestFactory.create<NestExpressApplication>(AppModule);
app.useStaticAssets(join(__dirname, '..', 'public'), { prefix: '/static'});
// const app = await NestFactory.create(AppModule);
await app.listen(3000);
}
bootstrap();
在根目录创建public
,然后创建一个index.html
文件。
访问http://localhost:3000/static/index.html,即可看到页面。
然后我们在index.html
添加一个接口氢气。修改文件中的内容,试着访问一个param
形式的接口
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="https://unpkg.com/axios@0.24.0/dist/axios.min.js"></script>
</head>
<body>
<script>
async function urlParam() {
const res = await axios.get('/api/person/1');
console.log(res);
}
urlParam();
</script>
</body>
</html>
打开页面中的控制台,发现接口已经返回数据请求了
OK,现在一切准备就绪,接下来我们通过nest接口和前端进行联调的方式来认识五种数据HTTP数据传输方式。
1.url param
现在我们如下一个请求地址:
http://xiumubai.com/person/1111
这里的 1111
就是路径中的参数(url param),服务端框架或者单页应用的路由都支持从 url 中取出参数。
示例代码:
@Get(':id')
findOne(@Param('id') id: string) {
return this.personService.findOne(+id);
}
修改index.html
中的请求如下:
const res = await axios.get('/api/person/1');
这里的1
就是我们拿到的id
。这个就是一个最基本的通过param传递数据的方式。
2.query
http://xiumubai.com/person?name=xiumubai&age=20
这里的 name
和 age
就是 query
传递的数据
示例代码:
@Get('find')
query(@Query('name') name: string, @Query('age') age: number) {
return `recived name:${name}, age: ${age}`;
}
const res = await axios.get('/api/person/find', {
params: {
name: '白哥',
age: 18
}
});
这里我们传参的方式就变成了
{
params: {
name: '白哥',
age: 18
}
}
3.form-urlencoded
直接用 form 表单提交数据就是这种,它和 query 字符串的方式的区别只是放在了 body 里,然后指定下 content-type 是 application/x-www-form-urlencoded
。
示例代码:
@Post()
create(@Body() createPersonDto: CreatePersonDto) {
return `received: ${JSON.stringify(createPersonDto)}`;
// return this.personService.create(createPersonDto);
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="https://unpkg.com/axios@0.24.0/dist/axios.min.js"></script>
<script src="https://unpkg.com/qs@6.10.2/dist/qs.js"></script>
</head>
<body>
<script>
async function urlParam() {
const res = await axios.post('/api/person', Qs.stringify({
name: '白哥',
age: 20
}), {
headers: { 'content-type': 'application/x-www-form-urlencoded' }
});
console.log(res);
}
urlParam();
</script>
</body>
</html>
其实比起 form urlencoded,使用 json 来传输更常用一些:
4.form-data
form data 不再是通过 & 分隔数据,而是用 --------- + 一串数字做为 boundary 分隔符。因为不是 url 的方式了,自然也不用再做 url encode。
form-data 需要指定 content type 为 multipart/form-data,然后指定 boundary 也就是分割线。
body 里面就是用 boundary 分隔符分割的内容。
Nest 解析 form data 使用 FilesInterceptor 的拦截器,用 @UseInterceptors 装饰器启用,然后通过 @UploadedFiles 来取。非文件的内容,同样是通过 @Body 来取。
示例代码:
@Post('file')
@UseInterceptors(
AnyFilesInterceptor({
dest: 'uploads/',
}),
)
filebody(
@Body() createPersonDto: CreatePersonDto,
@UploadedFiles() files: Array<Express.Multer.File>,
) {
console.log(files);
return `received: ${JSON.stringify(createPersonDto)}`;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="https://unpkg.com/axios@0.24.0/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>
可以看到,我们在nest中已经接收到了文件。
5.json
form-urlencoded 需要对内容做 url encode,而 form data 则需要加很长的 boundary,两种方式都有一些缺点。如果只是传输 json 数据的话,不需要用这两种。
可以直接指定content type 为 application/json 就行。
我们平时传输 json 数据基本用的是这种。
示例:
@Post()
create(@Body() createPersonDto: CreatePersonDto) {
return `received: ${JSON.stringify(createPersonDto)}`;
}
前端代码使用 axios 发送 post 请求,默认传输 json 就会指定 content type 为 application/json,不需要手动指定:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="https://unpkg.com/axios@0.24.0/dist/axios.min.js"></script></script>
</head>
<body>
<script>
async function urlParam() {
const res = await axios.post('/api/person', {
name: '白哥',
age: 20
});
console.log(res);
}
urlParam();
</script>
</body>
</html>
现在我们在日常开发传递POST参数基本上都是通过这种方式来开发。
以上就是我们在开发中遇到的5种常见的HTTP数据传输方式。