前言
HTTP 协议是以 ASCII 码传输,建立在 TCP/IP 协议之上的应用层规范。规范把 HTTP 请求分为三个部分:状态行、请求头、消息主体。类似于下面这样:
<method> <request-URL> <version>
<headers>
<entity-body>
协议规定 POST 提交的数据必须放在消息主体(entity-body)中,但协议并没有规定数据必须使用什么编码方式。实际上,开发者完全可以自己决定消息主体的格式,只要最后发送的 HTTP 请求满足上面的格式就可以。
但是,数据发送出去,还要服务端解析成功才有意义。一般服务端语言如 php、python ,java等,以及它们的 framework,都内置了自动解析常见数据格式的功能。服务端通常是根据请求头(headers)中的 Content-Type 字段来获知请求中的消息主体是用何种方式编码,再对主体进行解析。post提交数据有四种方式,下面介绍他们以及前端应该如何传参
一、Content-Type设置为application/x-www-form-urlencoded
传统的这种格式表单通过$(“form”).serialize()方法将参数序列化变成形如key&value的格式,然后传给后台解析现,如今serialize()在vue/angula/react等前端框架中都不怎么用了,如果要使用这种编码传输,可以使用npm的qs
1.使用qs
qs可以将json序列化如下:
let a = {
name:'june',
age:26
}
qs.stringify(a) //"name=june&age=26" qs可以将josn对象转换成形如key&value
如何使用:
import qs from 'qs'
let data = {code: 'fds', headImgUrl: '99', innerDemoVos: [{code: '篮球', name: 'xx'}, {code: '台球', name: '小芳'}]}
let params = qs.stringify(data, {arrayFormat: 'indices', allowDots: true})
// post的content-type的格式需要设置成application/x-www-form-urlencoded,data就是post请求体。
let data = {code: 'fds', headImgUrl: '99', innerDemoVos: [{code: '篮球', name: 'xx'}, {code: '台球', name: '小芳'}]};
// 将json对象转换成form表单的key&value的形式,包括复杂的数组对象,注意{arrayFormat: 'indices', allowDots: true}参数,一定要写,这个关系到数组对象转换成的格式后台是否可以解析,如果不写那么数组对象就是innerDemo[0].[code]: 篮球,这样后台是无法解析,只有innerDemo[0].code: 篮球的格式才可以解析,
console.info(qs.stringify(data, {arrayFormat: 'indices', allowDots: true}));
2.自定义全局方法
//utils->utils.js
export function objserialize (obj) {
let str = ''
for (var key in obj) {
str += key + '=' + obj[key] + '&'
}
return str.slice(0, -1)
}
//在组件中引入
import {objTostring} from "@/utils/utils"
let data = {
name: 'xiaoming',
age: 18,
}
let params = objTostring(data) //name='xiaoming'&age=18
二、Content-Type设置为application/json
这种编码格式现在比较流行推荐使用,前端传参不用管数据结构有多复杂层次有多深直接以json形式传就ok,不用像上面的转key&value的形式。实例
let param = {
name : 'xiaohong',
age: 18,
sex: '女',
goods: {
a: 1,
b:2
}
}
传参直接传json对象param,非常简单
三、Content-Type设置为 multipart/form-data
这也是常见的post请求方式,一般用来上传文件图片等,各大服务器的支持也比较好。
//在vue的js中
data(){
return{
params:{
file:"",//上传文件
}
}
}
methods:{
update(){
let fd = this.transformData(this.params)
let api = '/api/updateFile'
this.axios.post(api,fd,{
headers:{
"content-type":"multipart/form-data"
}
}).then(res=>{
console.log(res)
})
},
// 转化为formdata格式
transformData(obj){
let fd = new FormData()
Object.keys(obj).forEach(key=>{
fd.append(key,obj[key])
})
return fd
}
}
四、Content-Type设置为 text/xml
它是一种使用 HTTP 作为传输协议,XML 作为编码方式的远程调用规范。典型的 XML-RPC 请求是这样的:
POST http://www.example.com HTTP/1.1
Content-Type: text/xml
<!--?xml version="1.0"?-->
<methodcall>
<methodname>examples.getStateName</methodname>
<params>
<param>
<value><i4>41</i4></value>
</params>
</methodcall>
XML-RPC 协议简单、功能够用,各种语言的实现都有,但是个人觉得略显臃肿,没有Json格式简单灵活
总结
平时开发中有时候会出现参数格式错误一定要注意查看Content-Type设定值,以及跟后端沟通