请求提交数据方式

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--
相关推荐
吃杠碰小鸡19 分钟前
commitlint校验git提交信息
前端
虾球xz1 小时前
游戏引擎学习第20天
前端·学习·游戏引擎
我爱李星璇1 小时前
HTML常用表格与标签
前端·html
疯狂的沙粒1 小时前
如何在Vue项目中应用TypeScript?应该注意那些点?
前端·vue.js·typescript
小镇程序员1 小时前
vue2 src_Todolist全局总线事件版本
前端·javascript·vue.js
野槐1 小时前
前端图像处理(一)
前端
程序猿阿伟1 小时前
《智能指针频繁创建销毁:程序性能的“隐形杀手”》
java·开发语言·前端
疯狂的沙粒1 小时前
对 TypeScript 中函数如何更好的理解及使用?与 JavaScript 函数有哪些区别?
前端·javascript·typescript
瑞雨溪2 小时前
AJAX的基本使用
前端·javascript·ajax
力透键背2 小时前
display: none和visibility: hidden的区别
开发语言·前端·javascript