NestJS 开发必备:HTTP 接口传参的 5 种方式总结与实战

【NestJS】HTTP 接口传参的 5 种方式

在前后端开发中,HTTP 接口的数据传输方式有多种,常见的有 query、url param、form-urlencoded、form-data、json 。 作为前端,我们不仅要知道如何调用,还要理解后端如何接收。今天我们用 NestJS 来演示这几种方式。


目录

  • [1. Query 参数](#1. Query 参数 "#1-query-%E5%8F%82%E6%95%B0")
  • [2. URL Param 参数](#2. URL Param 参数 "#2-url-param-%E5%8F%82%E6%95%B0")
  • [3. Form-Urlencoded](#3. Form-Urlencoded "#3-form-urlencoded")
  • [4. Form-Data](#4. Form-Data "#4-form-data")
  • [5. JSON](#5. JSON "#5-json")
  • 总结

1. Query 参数

参数位置

  • 写在 URL ? 后面 ,多个参数用 & 分隔
  • 例如: GET /person?name=三十&age=18

前端调用

csharp 复制代码
// axios 方式
axios.get('/api/person', {
  params: { name: '三十', age: 18 }
});
​
// 或者直接拼接
axios.get('/api/person?name=三十&age=18');

后端定义

less 复制代码
@Controller('api/person')
export class PersonController {
  @Get('/query')
  queryHandle(@Query('name') name: string, @Query('age') age: number) {
    return `[三十] queryHandle received name=${name}, age=${age}`;
  }
}

2. URL Param 参数

参数位置

  • 直接放在 URL 路径中
  • 例如:GET /person/18

前端调用

csharp 复制代码
axios.get('/api/person/18');

后端定义

less 复制代码
@Controller('api/person')
export class PersonController {
  @Get(':id') // 声明参数,定义多个参数: @Get(':id/:age/:name')
  urlParamHandle(@Param('id') id: string) { // @Param() 装饰器,取出参数注入到 Controller 方法中
    return `[三十] urlParamHandle received id=${id}`;
  }
}

注意点: 静态路由和动态路由定义顺序

静态路由(find、list、detail 等)要放在前面, 动态路由(:id、:slug 等)要放在后面 ,否则静态路由会被动态路由"吃掉"

kotlin 复制代码
@Controller('api/person')
export class PersonController {
    @Get('find') // 静态路由
    findAll() {
      return 'find all';
    }
    
    @Get(':id') // 动态路由
    getById(@Param('id') id: string) {
      return { id };
    }
}

3. Form-Urlencoded

参数位置

  • 写在 body 里 ,格式类似 name=三十&age=18

    非英文字符和其他需要编码的字符可以通过 encodeURIComponent('三十') 编码或使用 query-string npm 包处理

  • Content-Type: application/x-www-form-urlencoded

前端调用

php 复制代码
import qs from 'qs';
​
const res = await axios.post('/api/person', qs.stringify({
    name: '三十',
    age: 18
  }), {
    headers: { 'content-type': 'application/x-www-form-urlencoded' }
  });

后端定义(NestJS)

less 复制代码
// dto 是 data transfer object,用于封装传输的数据的对象
class CreatePersonDto {
  name: string;
  age: number;
}
​
@Controller('api/person')
export class PersonController {
  @Post()
  formUrlEncodedHandle(@Body() createPersonDto: CreatePersonDto) { // 使用 @Body 装饰器,Nest 会解析请求体,然后注入到 dto 中。
    return `[三十] formUrlEncodedHandle received ${JSON.stringify(createPersonDto)}`
  }
}

4. Form-Data

参数位置

  • 也是写在 body 中

  • 使用 boundary 分隔,支持上传 文件

  • Content-Type: multipart/form-data

前端调用

kotlin 复制代码
import axios from 'axios'
const fileInput = document.querySelector('#fileInput');
​
async function formData() {
  const data = new FormData();
  data.set('name','三十');
  data.set('age', 18);
  data.set('file1', fileInput.files[0]);
  data.set('file2', fileInput.files[1]);
​
  axios.post('/api/person/file', data, {
    headers: { 'content-type': 'multipart/form-data' }
  });
}
​
fileInput.onchange = formData;

后端定义

less 复制代码
import {
  Body,
  UseInterceptors,
  UploadedFiles,
} from '@nestjs/common';
import { PersonService } from './person.service';
import { AnyFilesInterceptor } from '@nestjs/platform-express';
​
@Controller('api/person')
export class PersonController {
  @Post('file')
  @UseInterceptors(
    AnyFilesInterceptor({
      dest: 'upload/', // 默认上传文件存放的目录
    }),
  )
  formDataHandle(
    @Body() createPersonDto: CreatePersonDto,
    @UploadedFiles() files: Array<Express.Multer.File>,
  ) {
    console.log(files);
    return `[三十] formDataHandle received ${JSON.stringify(createPersonDto)}`;
  }
}

5. JSON

参数位置

  • 写在 body 中
  • Content-Type: application/json

前端调用

php 复制代码
axios.post('/api/person', {
  name: '三十',
  age: 18
});

后端定义(NestJS)

less 复制代码
@Controller('api/person')
export class PersonController {
  @Post()
  applicationJsonHandle(@Body() createPersonDto: CreatePersonDto) {
    return `[三十] applicationJsonHandle received ${JSON.stringify(createPersonDto)}`;
  }
}

总结

方式 参数位置 Content-Type 前端调用示例 NestJS 装饰器
Query URL ? 后面 无需特殊设置 axios.get('/api?x=1') @Query
URL Param URL 路径 无需特殊设置 axios.get('/api/1') @Param
Form-Urlencoded body(字符串) application/x-www-form-urlencoded axios.post(url, qs.stringify()) @Body
Form-Data body(分隔符) multipart/form-data axios.post(url, formData) @Body + @UploadedFile
JSON body(JSON) application/json axios.post(url, { obj }) @Body
相关推荐
donecoding2 分钟前
Corepack 完全解析:从懵到懂,包管理器自由了
前端·node.js·前端工程化
yqcoder5 分钟前
端经典面试题:为什么 0.1 + 0.2 !== 0.3?
前端·css
ZC跨境爬虫10 分钟前
跟着 MDN 学 HTML day_12:(HTML网页图片嵌入)
前端·javascript·css·ui·html
光影少年16 分钟前
reeact虚拟DOM、Diff算法原理、key的作用与为什么不能用index
前端·react.js·掘金·金石计划
用户0595401744621 分钟前
大模型记忆存储踩坑实录:LangChain 的 ConversationBufferMemory 让我排查了 6 小时
前端·css
用户94161469336522 分钟前
Python 实时监控 A 股行情并自动筛选强势股(REST + WebSocket 两种方案)
后端·数据分析
Java编程爱好者24 分钟前
吃透 ForkJoinPool:工作窃取底层原理,一次性讲透
后端
是上好佳佳佳呀28 分钟前
【前端(十二)】JavaScript 函数与对象笔记
前端·javascript·笔记
longxibo30 分钟前
【Flowable 7.2 源码深度解析与实战】
java·后端·流程图
雨辰AI39 分钟前
从 MySQL 迁移至人大金仓 V9 完整改造指南|分页 / 函数 / 语法兼容全部解决
java·开发语言·数据库·后端·mysql·政务