当前位置: 首页 > ds >正文

【NestJS】HTTP 接口传参的 5 种方式(含前端调用与后端接收)

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

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


目录

  • 1. Query 参数
  • 2. URL Param 参数
  • 3. Form-Urlencoded
  • 4. Form-Data
  • 5. JSON
  • 总结

1. Query 参数

参数位置

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

前端调用

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

后端定义

@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

前端调用

axios.get('/api/person/18');

后端定义

@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 等)要放在后面 ,否则静态路由会被动态路由“吃掉”

@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

前端调用

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)

// 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

前端调用

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;

后端定义

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

前端调用

axios.post('/api/person', {name: '三十',age: 18
});

后端定义(NestJS)

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

总结

方式参数位置Content-Type前端调用示例NestJS 装饰器
QueryURL ? 后面无需特殊设置axios.get('/api?x=1')@Query
URL ParamURL 路径无需特殊设置axios.get('/api/1')@Param
Form-Urlencodedbody(字符串)application/x-www-form-urlencodedaxios.post(url, qs.stringify())@Body
Form-Databody(分隔符)multipart/form-dataaxios.post(url, formData)@Body + @UploadedFile
JSONbody(JSON)application/jsonaxios.post(url, { obj })@Body
http://www.xdnf.cn/news/19801.html

相关文章:

  • 【卷积神经网络】卷积神经网络的三大核心优势:稀疏交互、参数共享与等变表示
  • C++之基于正倒排索引的Boost搜索引擎项目介绍
  • 如何解决pip安装报错ModuleNotFoundError: No module named ‘black’问题
  • 【提示词】...(后续单元)在Prompt 的作用
  • 【linux仓库】万物至简的设计典范:如何用‘文件’这一个概念操纵整个Linux世界?
  • 在Docker中安装MySQL时3306端口占用问题
  • 论文学习30:LViT: Language Meets Vision Transformerin Medical Image Segmentation
  • 使用云手机进行游戏搬砖划算吗?
  • 国内真实的交换机、路由器和分组情况
  • 【保姆级喂饭教程】把chrome谷歌浏览器中的插件导出为CRX安装包
  • LeetCode 925.长按键入
  • 数据结构:希尔排序 (Shell Sort)
  • 【51单片机】【protues仿真】基于51单片机呼叫系统
  • 基于Force-closure评估的抓取计算流程
  • 生成知识图谱与技能树的工具指南:PlantUML、Mermaid 和 D3.js
  • 【AI报表】JimuReport 积木报表 v2.1.3 版本发布,免费可视化报表和大屏
  • 【leetcode】222. 完全二叉树的节点个数
  • Altium Designer中的Net-Tie:解决多网络合并与电气隔离的利器
  • CPTS-Vintage 票据,基于资源的约束委派 (RBCD),DPAPI密钥
  • 自制扫地机器人(二) Arduino 机器人避障设计——东方仙盟
  • Veo Videos Generation API 对接说明
  • 鸿蒙NEXT表单选择组件详解:Radio与Checkbox的使用指南
  • 开源 C++ QT Widget 开发(十)IPC进程间通信--共享内存
  • 零跑汽车8月交付57066台,同比增长超88%
  • amd cpu是x86架构吗
  • 【Audio】静音或振动模式下重复来电响铃
  • stdexcept介绍与使用指南
  • 【LeetCode】3670. 没有公共位的整数最大乘积 (SOSDP)
  • Day19_【机器学习—线性回归 (3)—回归模型评估方法】
  • Docker一键快速部署压测工具,高效测试 API 接口性能