深度解析Vue使用axios发起HTTP请求
使用axios时,配置选项中包含params和data两项,它们是有区别的:
1、params是添加到url的请求字符串中的,用于get请求。 (get请求中没有data传值方式)
2、data是添加到请求体(Request Body)中的, 一般用于post请求。(post请求也可以使用params方式传值,除Request Method为POST外,其他同get)
axios get请求params修改为data,显然是不能请求成功的,因为get请求中不存在data这个选项。
浏览器携带参数请求的三种形式:
1、Query String Parameters
参数会以url string的形式进行传递。即?后的字符串则为其请求参数,并以&作为分隔符。
2、Form Data
参数不会显式出现在请求url中,在Form Data中,并以&作为分隔符的字符串
3、Request Payload
参数不会显式出现在请求url中,在Request Payload中,数据格式为JSON
下面是以Google Chrome 版本 84.0.4147.135(正式版本) (64 位)实际测试
1、get请求传入params参数:表单参数以name=value&name1=value1的形式附到url的后面;没有Content-Type 项,参数在Query String Parameters中。
axios({
method: "get",
url: "http://localhost:8080/test",
params : {
id: '123456789',
name: '张三',
storeIds: [1,2,3],
obj:{oid:"123",oname:"对象",num:666}
},
})
传输的内容为:id=123456789&name=%E5%BC%A0%E4%B8%89&storeIds[]=1&storeIds[]=2&storeIds[]=3&obj=%7B%22oid%22:%22123%22,%22oname%22:%22%E5%AF%B9%E8%B1%A1%22,%22num%22:666%7D
编码方式:URL编码
2、post请求传入params参数:表单参数还是以name=value&name1=value1的形式附到url的后面;没有Content-Type 项,参数在Query String Parameters中。
axios({
method: "post",
url: "http://localhost:8080/test",
params : {
id: '123456789',
name: '张三',
storeIds: [1,2,3],
obj:{oid:"123",oname:"对象",num:666}
},
})
传输的内容为:id=123456789&name=%E5%BC%A0%E4%B8%89&storeIds[]=1&storeIds[]=2&storeIds[]=3&obj=%7B%22oid%22:%22123%22,%22oname%22:%22%E5%AF%B9%E8%B1%A1%22,%22num%22:666%7D
编码方式:URL编码
3、post请求传入data参数,未指定请求头RequestHeader,默认使用Content-Type是text/plain;charset=UTF-8。 参数在Request Payload中。
Payload Content-Type: 'application/json; charset=utf-8'
axios({
method: "post",
url: "http://localhost:8080/product/create",
data:{
id: '123456789',
name: '张三',
storeIds: [1,2,3],
obj:{oid:"123",oname:"对象",num:666}
}
})
传输的内容为:{"id":"123456789","name":"张三","storeIds":[1,2,3],"obj":{"oid":"123","oname":"对象","num":666}}
编码方式:JSON
4、post请求传入data参数,指定请求头RequestHeader Content-Type: application/x-www-form-urlencoded 参数在Form Data中。
Form Data Content-Type: 'application/x-www-form-urlencoded'
axios({
method: "post",
url: "http://localhost:8080/product/create",
data:{
id: '123456789',
name: '张三',
storeIds: [1,2,3],
obj:{oid:"123",oname:"对象",num:666}
},
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
}
})
传输的内容为:{"id":"123456789","name":"张三","storeIds":[1,2,3],"obj":{"oid":"123","oname":"对象","num":666}}
编码方式:JSON
5、post请求传入data参数,指定请求头RequestHeader Content-Type: application/x-www-form-urlencoded 并序列化表单参数传输, 参数在Form Data中。
axios({
headers: {
'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'
},
transformRequest: [function(data) { //在请求之前对data传参进行格式转换
data = Qs.stringify(data)
return data
}],
url:'/product/create',
method:'post',
data:{
id: '123456789',
name: '张三',
storeIds: [1,2,3],
obj:{oid:"123",oname:"对象",num:666}
}
})
传输的内容为:id=123456789&name=%E5%BC%A0%E4%B8%89&storeIds%5B0%5D=1&storeIds%5B1%5D=2&storeIds%5B2%5D=3&obj%5Boid%5D=123&obj%5Boname%5D=%E5%AF%B9%E8%B1%A1&obj%5Bnum%5D=666
编码方式:URL编码
6、普通HTML表单POST方式:请求头Content-Type: application/x-www-form-urlencoded,Form Data : firstname=%E7%8E%8B%E5%AE%89%E6%88%90&lastname=22222 内容是经过编码的
测试完成 结论:
普通HTML表单POST提交时,使用的Content-Type是application/x-www-form-urlencoded,而使用原生AJAX的POST请求如果不指定请求头RequestHeader,默认使用的Content-Type是text/plain;charset=UTF-8。
在html中form的Content-type默认值:Content-type:application/x-www-form-urlencoded
如果使用axios请求,在请求头中出现 request payload导致参数的方式改变了 ,那么解决办法就是:
设置header的content-type为application/x-www-form-urlencoded
headers: {'Content-Type':'application/x-www-form-urlencoded'}
同时还要序列化请求参数变为以&作为分隔符的字符串
当axios请求为post,表单提交时,
而表单数据不进行序列化,在请求体中的数据为:{"id":"123456789","name":"张三","storeIds":[1,2,3],"obj":{"oid":"123","oname":"对象","num":666}}
后台是接收不到参数的,必须进行序列化。
序列化方法:序列化解析插件qs
qs 是一个增加了一些安全性的查询字符串解析和序列化字符串的库。
在项目中使用命令行工具输入:cnpm install qs --save
安装完成后在需要用到的组件中:import Qs from 'qs'
具体使用中:Qs.parse()和Qs.stringify()
这两种方法虽然都是序列化,但是还是有区别的。
Qs.parse()是将URL解析成对象的形式
Qs.stringify()是将对象 序列化成URL的形式,以&进行拼接
axios({
headers: {
'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'
},
transformRequest: [function(data) { //在请求之前对data传参进行格式转换
data = Qs.stringify(data)
return data
}],
url:'/product/create',
method:'post',
data:{
id: '123456789',
name: '张三',
storeIds: [1,2,3],
obj:{oid:"123",oname:"对象",num:666}
}
})