我们知道,HTTP 协议是以 ASCII 码传输,建立在 TCP/IP 协议之上的应用层规范。
规范把 HTTP 请求分为三个部分:状态行、请求头、消息主体。类似于下面这样:
Content-Type就是指 HTTP 发送信息至服务器时的内容编码类型,服务器根据编码类型使用特定的解析方式,获取数据流中的数据。
协议规定 POST 提交的数据必须放在消息主体(entity-body)中,但协议并没有规定数据必须 使用什么编码方式 。实际上,开发者完全可以自己决定消息主体的格式,只要最后发送的 HTTP 请求满足上面的格式就可以。
但是,数据发送出去,还要服务端解析成功才有意义。一般服务端语言如 php、python 等,以及它们的 framework,都内置了自动解析常见数据格式的功能。
服务端通常是根据请求头(headers)中的 Content-Type 字段来获知请求中的消息主体是用何种方式编码,再对主体进行解析。
所以说到 POST 提交数据方案,包含了 Content-Type 和消息主体编码方式两部分。
这里主要关注 Content-Type 和 data 的处理
现在这种格式也变得越来越常用了,主要是便于处理复杂对象,JSON 格式支持比键值对复杂得多的结构化数据
postJson = (url, data = {}) => {
return this.fetch(url, {
headers: {
'Content-Type': 'application/json;charset=UTF-8'
},
method: 'POST',
body: JSON.stringify(data)
});
};
这种格式经常用于上传文件
postFormData = (url, data = {}) => {
const formData = new FormData();
Object.keys(data).forEach(key => {
formData.append(key, data[key]);
});
return this.fetch(url, {
headers: {
'Content-Type': 'multipart/form-data'
},
method: 'POST',
body: formData
});
};
当action为get时候,浏览器用x-www-form-urlencoded的编码方式把form数据转换成一个字串(name1=value1& amp; amp;name2=value2…),然后把这个字串append到url后面,用?分割,加载这个新的url。
当action为post时候,浏览器把form数据封装到http body中,然后发送到server。
所有数据变成键值对的形式 key1=value1&key2=value2的形式,并且特殊字符需要转义成utf-8编号,如空格会变成 %20;
post = (url, data) => {
return this.fetch(url, {
headers: {
'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8'
},
method: 'POST',
body: qs.stringify(data)
});
};
这种转化为键值对的方式只适合于简单的对象,如果是复杂的嵌套对象,还是应该用 application/json, x-www-form-urlencoded 会转成复杂的格式
param2 = {
a: '1111',
b: {
c: '2222',
d: '333'
}
};
---->
a=1111&b[c]=2222&b[d]=333
参考链接
POST提交数据之—Content-Type的理解;
四种常见的 POST 提交数据方式 专题