学习笔记:POST方法与Content-Type数据格式

序言

之所以写下此篇笔记,是因为前几天在与后端联调的时候,双方对数据传递的格式出现了分歧,正当我想为自己辩护时,却发现自己竟然连几种常见的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,直接导致没法对二进制数据编码。

image.png

当你在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);
})
复制代码
© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享