请求提交数据方式

GET请求

GET请求没有请求体,参数包含在URL中。

查询字符串

查询字符串(Query String):在URL中使用?符号将参数附加到URL末尾,多个参数之间使用&符号分隔。

js 复制代码
GET /api/users?id=890418&name=Jessica HTTP/1.1

RESTful风格

RESTful风格的URL参数:将参数直接作为URL的一部分,一般用于表示资源的唯一标识符或路径参数

js 复制代码
GET /api/users/890418 HTTP/1.1

数组

参数传入数组:使用相同的参数名,但允许多个值的情况

方式1:

js 复制代码
GET http://localhost:8080/api/users?roleIds=1&roleIds=2 HTTP/1.1

方式2:

js 复制代码
GET http://localhost:8080/users?roleIds=1,2 HTTP/1.1

方式3:

js 复制代码
GET http://localhost:8080/users?roleIds[]=1&roleIds[]=2 HTTP/1.1

方式4:

js 复制代码
GET http://localhost:8080/api/users?roleIds[0]=1&roleIds[1]=2 HTTP/1.1

后端get接口设计接受数组型查询参数时,只接受重复的query格式,如 arr=[1,2,3],那么在query里的参数格式需要是a=1&a=2&a=3,前端get请求直接传数组会默认处理为a[]=1&a[]=2&a[]=3,后端无法识别。

可以借助qs库,对axios请求封装paramsSerializer(params处理函数),是一个负责 params 序列化的函数。

js 复制代码
import qs from 'qs'
qs.stringify({ a: ["b", "c", "d"] }); // a[0]=b&a[1]=c&a[2]=d
qs.stringify({ a: ["b", "c", "d"] }, { indices: false }); // a=b&a=c&a=d
// qs 还可以通过arrayFormat 选项进行格式化输出
qs.stringify({ a: ["b", "c"] }, { arrayFormat: "indices" }) // a[0]=b&a[1]=c
qs.stringify({ a: ["b", "c"] }, { arrayFormat: "brackets" }) // a[]=b&a[]=c
qs.stringify({ a: ["b", "c"] }, { arrayFormat: "repeat" }) // a=b&a=c
qs.stringify({ a: ["b", "c"] }, { arrayFormat: "comma" }) // a=b,c
js 复制代码
import axios from 'axios'
axios.get({
  url: '/user',
  method: 'get', 
  baseURL: 'https://localhost:8080/api/',
  // `paramsSerializer` 是一个负责 `params` 序列化的函数
  paramsSerializer: paramsSerializer: (params) => qs.stringify(params, { arrayFormat: 'repeat' })
})
js 复制代码
// 请求拦截器,在请求发送前格式化
axios.interceptors.request.use(async (config) => {
//只针对get方式进行序列化
 if (config.method === 'get') {
   config.paramsSerializer = function(params) {
     return qs.stringify(params, { arrayFormat: 'repeat' })
   }
 }
}

需要注意的是,如果请求参数中带有中括号[][]在url中属于功能性字符,前端需要使用decodeURIComponent()函数转义,否则会出现400 Bad Request错误。

js 复制代码
qs.stringify({ a: ['b', 'c', 'd'] });  // a%5B0%5D=b&a%5B1%5D=c&a%5B2%5D=d
decodeURIComponent(qs.stringify({ a: ["b", "c", "d"] }) // a[0]=b&a[1]=c&a[2]=d

对象

将参数封装在一个对象中,然后将该对象作为查询字符串的值传递。

直接传一个对象作为参数是不对的,后端无法识别出来。需要把对象序列化成字符串,然后通过decodeURIComponent()函数转义后加到url中

js 复制代码
GET http://localhost:8080/users?param={"accID":"milo","field":"nick_name,email"} HTTP/1.1
js 复制代码
const queryparam = {accID:"milo",field:"nick_name,email"}
// 利用JSON.stringify转化为JSON格式,再利用decodeURIComponent()方法转义。
decodeURIComponent(JSON.stringify(queryparam))

POST

JSON 数据格式

在请求的数据体中使用 JSON 格式来传递参数。application/json作为Content-Type的请求头,用来告诉服务端消息主体是序列化后的 JSON 字符串。

js 复制代码
POST http://localhost:8080/api/users HTTP/1.1 
Content-Type: application/json 

{ 
    "name": "Jessica",
    "bir": 890418
}

表单数据格式

在请求的数据体中使用表单数据格式来传递参数。这是最常见的 POST 提交数据的方式,浏览器的原生 form 表单,如果不设置 enctype 属性,那么最终就会以application/x-www-form-urlencoded方式提交数据。application/x-www-form-urlencoded作为Content-Type的请求头。

js 复制代码
POST http://localhost:8080/api/users HTTP/1.1 
Content-Type: application/x-www-form-urlencoded

name=hyomin&bir=890530

文件上传格式

在请求的数据体中使用多部分表单数据格式来传递参数,适用于文件上传等场景。使用表单上传文件时,必须让 form 的 enctyped 等于multipart/form-data这个值。application/multipart/form-data作为Content-Type的请求头。

首先会生成一个boundary用于分割不同的字段,为了避免与正文内容重复,boundary 很长很复杂。然后Content-Type里指明了数据是以mutipart/form-data 来编码,本次请求的 boundary的内容在消息主体里按照字段个数又分为多个结构类似的部分,每部分都是以--boundary 开始,紧接着内容描述信息,最后是字段具体内容(文本或二进制)。如果传输的是文件,还要包含文件名和文件类型信息。消息主体最后以 --boundary-- 标示结束。

以下包含了一个文件字段 file:file的内容是图片的二进制数据

js 复制代码
POST http://localhost:8080/api/upload HTTP/1.1 
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryABC123

------WebKitFormBoundaryABC123
Content-Disposition: form-data; name="file"; filename="example.jpg" 
Content-Type: image/jpeg

[file content(文件的二进制流)]
------WebKitFormBoundaryABC123--

以下包含一个text字段和file字段,text字段的内容是字符串titlefile字段的内容是图片的二进制流数据

js 复制代码
POST http://www.example.com HTTP/1.1

Content-Type:multipart/form-data; boundary=----WebKitFormBoundaryrGKCBY7qhFd3TrwA`

------WebKitFormBoundaryrGKCBY7qhFd3TrwA
Content-Disposition: form-data; name="text"

title
------WebKitFormBoundaryrGKCBY7qhFd3TrwA
Content-Disposition: form-data; name="file"; filename="chrome.png"
Content-Type: image/png

PNG ... content of chrome.png ...
------WebKitFormBoundaryrGKCBY7qhFd3TrwA--
相关推荐
GISer_Jing5 分钟前
前端面试通关:Cesium+Three+React优化+TypeScript实战+ECharts性能方案
前端·react.js·面试
落霞的思绪1 小时前
CSS复习
前端·css
咖啡の猫3 小时前
Shell脚本-for循环应用案例
前端·chrome
百万蹄蹄向前冲5 小时前
Trae分析Phaser.js游戏《洋葱头捡星星》
前端·游戏开发·trae
朝阳5816 小时前
在浏览器端使用 xml2js 遇到的报错及解决方法
前端
GIS之路6 小时前
GeoTools 读取影像元数据
前端
ssshooter6 小时前
VSCode 自带的 TS 版本可能跟项目TS 版本不一样
前端·面试·typescript
Jerry7 小时前
Jetpack Compose 中的状态
前端
dae bal8 小时前
关于RSA和AES加密
前端·vue.js
柳杉8 小时前
使用three.js搭建3d隧道监测-2
前端·javascript·数据可视化