前面会有一些基础的介绍,懂的人可跳过前面的基础介绍直接copy文档末尾的代码
基础介绍开始
一般post不允许发送复杂数据类型,比如object和array,而jquery的ajax封装了这个方法,使得可以发送复杂数据格式,
代码
$.ajax({
type: 'POST',
url: 'http://www.skybseo.cn/php/jiekou.php',
data: {
firstName: "Fred",
lastName: "Flintstone",
boj:{
n:1,
name:'张三',
sex:0
},
list:['张三','李四','王五','赵六'],
listobj:[
{id:1,name:'张三'},
{id:2,name:'李四'}
]
},
success: (res)=>{
console.log(res)
},
// dataType: dataType
});
消息体中的格式为
然而vue指定的ajax插件axios没有封装这样的功能,并且默认的post请求大不一样。
这是和请求消息头中的content-type字段的值有关,
content-type字段用于描述数据实体的类型,就是指定客户端要发送的数据类型
post请求中常见的content-type的值有四种
1.application/x-www-form-urlencoded
最常见的post的数据类型,也是表单提交的数据类型,jquery的ajax默认也是这个
2.multipart/form-data
文件上传时要使用的数据类型
3.application/json
json格式的数据类型,也是axios的默认类型
4.text/xml
现在这个很少用了,基本没见过
axios默认的数据类型为application/json,一般后台不能接受到post的请求的信息体,就是因为不能正确识别json请求,只要修改一下content-type就可以了,详见https://blog.csdn.net/weixin_41797287/article/details/80648119
比如用PHP的$_POST接收不到json类型的请求
基础介绍结束
那么如何让axios可以发送复杂数据格式,并让后端准确接收呢?
提供两个方法
axios插件提供了transformRequest方法,这个方法可以修改data中的值,
代码是我公司前端大佬写的,也是现在在做的项目一直用的,先看效果
贴代码
let data = {
id:1,
name:'李四',
arr:['张三','王五','赵六','刘七'],
list:[
{id:1,name:'周八',sex:1},
{id:2,name:'卢九',sex:0},
{id:3,name:'齐十',sex:1},
],
obj:{
title:'axios请求学习',
time:'2018-9-11'
}
}
// 这是定义的数据,基本数据类型和复杂数据类型都有
axios({
method: "POST",
url: 'http://www.skybseo.cn/php/jiekou.php', //测试URL,不可使用
data:data,
headers: {
'Content-Type': 'application/x-www-form-urlencoded', //指定消息格式
},
transformRequest: [function (e) {
// 数据转换的核心代码,来自我公司的前端大佬
function setDate(e){
var t, n, i, r, o, s, a, c = "";
for (t in e)
if (n = e[t], n instanceof Array)
for (a = 0; a < n.length; ++a)
o = n[a], i = t + "[" + a + "]", s = {}, s[i] = o, c += setDate(s) + "&";
else if (n instanceof Object)
for (r in n) o = n[r], i = t + "[" + r + "]", s = {}, s[i] = o, c += setDate(s) + "&";
else void 0 !== n && null !== n && (c += encodeURIComponent(t) + "=" + encodeURIComponent(n) + "&");
return c.length ? c.substr(0, c.length - 1) : c
}
// 数据转换的核心代码结束
return setDate(e)
}],
})
.then((res) => {
console.log(res)
})
.catch((err) => {
console.log(err)
})
思考一下:为什么axios要这么反人类的指定默认的传输数据格式为json,而不是常规的表单上传类型
因为json是目前数据传输最优秀的类型,易于理解,数据传输更快
目前后端向前端传递数据,几乎全部的公司实现了json传输
axios认为前端向后端传递数据也要使用json,但是目前服务器端一般都不会接收这样的数据,除了Node,因为node可以很轻松的指定接收数据的格式,在这方面node服务器比其他服务器更灵活。
那么如何更改后端代码才能接收json呢?
首先,我们先实现前端代码传递json,其实就是使用axios默认的传输就可以了
前端代码
let data = {
id:1,
name:'李四',
arr:['张三','王五','赵六','刘七'],
list:[
{id:1,name:'周八',sex:1},
{id:2,name:'卢九',sex:0},
{id:3,name:'齐十',sex:1},
],
obj:{
title:'axios请求学习',
time:'2018-9-11'
}
}
// console.log(data)
axios({
method: "POST",
url: 'jiekou.php',
data:data,
headers: {
'Content-Type': 'application/json;charset=UTF-8', //指定消息格式
},
})
.then((res) => {
console.log(res)
})
.catch((err) => {
console.log(err)
})
请求消息体中的数据
后端php接收代码(post接收不到)
返回数据为
目前几乎全部的接口返回的数据都是json,但前端上传通常使用multipart/form-data,如果要使用json发送复杂数据,一定要确保后端支持,如果不支持只能使用第一种方法封装axios,也许未来前端传递数据也会逐渐的被json替代。
欢迎交流