序言
之所以写下此篇笔记,是因为前几天在与后端联调的时候,双方对数据传递的格式出现了分歧,正当我想为自己辩护时,却发现自己竟然连几种常见的content-type都搞不清,进而被后端嘲讽自己连传什么格式都搞不清。
希望通过这篇笔记,能让自己牢记不爱总结、思考的下场。
POST
HTTP POST 方法 发送数据给服务器. 请求主体的类型由 Content-Type 首部指定。post请求除了使用html表单发送,还可以通过AJAX的方式发送。
POST / HTTP/1.1
Host: foo.com
Content-Type: application/x-www-form-urlencoded
Content-Length: 13
say=Hi&to=Mom
复制代码
Content-Type
Content-Type实体头部用于指示资源的MIME类型。在响应中,Content-Type标头告诉客户端实际返回的内容的内容类型。
在原生的form表单中,可以通过enctype这个字段指定content-type类型。
<form action="/" method="post" enctype="multipart/form-data">
<input type="text" name="description" value="some text">
<input type="file" name="myFile">
<button type="submit">Submit</button>
</form>
复制代码
在前后端的通信中,我们通常通过以下三种content-type类型定义数据格式,分别是application/x-www-form-urlencoded、multipart/form-data和application/json,下面我来分别介绍一下。
application/x-www-form-urlencoded
content-type: application/x-www-form-urlencoded; charset=UTF-8
复制代码
从urlencoded这个单词就可以看出,它的编码规则和url编码规则是一样的。在原生的form标签中,如果不显式的指定enctype属性,默认发送的数据就是application/x-www-form-urlencoded。如果你查看通过这种编码规则发送的请求,数据是这样的:
productId=94608&folderId=5fa00a2ce4b01e990ecee97b&skuId=440535
复制代码
在经过url编码过后,会变成这样:
encodeURIComponent("productId=94608&folderId=5fa00a2ce4b01e990ecee97b&skuId=440535")
// "productId%3D94608%26folderId%3D5fa00a2ce4b01e990ecee97b%26skuId%3D440535"
复制代码
是不是感觉很眼熟?因为他和get方法在url中传参是一样的,每组key/val通过&连接。这种数据格式和直接使用url的区别,只是把数据放在body里。
关于url编码,阮一峰大佬写过一篇博客,感兴趣的可以看一下关于URL编码
multipart/form-data
content-type: multipart/form-data; boundary=----WebKitFormBoundaryllpanFebLMmhdFGN
复制代码
如果你想要上传图片这种二进制文件,就必须用multipart/form-data格式传输数据,body通过boundary字段封装消息的多个部分的边界。
关于为什么上传二进制文件一定要通过multipart/form-data而不是application/x-www-form-urlencoded,是因为后者针对非字母或者数字的字符会使用Percent-encoding,直接导致没法对二进制数据编码。
当你在js中使用new FormData()的时候,最终传输的数据就是multipart/form-data这种格式
application/json
content-type: application/json; charset=UTF-8
复制代码
最简单也最常见的格式,适合结构化数据,尤其是数据层级较深的时候。由于前后端针对json格式的序列化与反序列化都是十分便捷,因此有大量数据交互场景是通过json格式传递数据的。
提交表单的场景中,除非涉及到文件上传,否则基本都是通过application/json这种数据提交表单信息。
值得注意的是,application/json会触发CORS预检请求,而上面提到的两种并不会。
networkService.post({
url: 'xxx/yyy',
data: JSON.stringify(data);
}).then(res => {
console.log(res);
}).catch(e => {
console.error(e);
})
复制代码