本文所讲的 POST 请求是 HTTP/1.1 协议中规定的众多 HTTP 请求方法的其中最常用的一个. 一般使用 POST 请求方法向服务器发送数据 (主要是一些创建更新操作), 本文讨论的是 POST 请求方法常用的四种数据提交格式.
由于 HTTP/1.1 协议中并没有对请求使用什么编码方式进行规定, 所以理论上开发者完全可以自己决定请求的 Body 体使用什么格式, 当然实际上大家都还是用通用的那么几种编码方式来提交数据 (生态很关键).
注: 以下排名不分先后...
application/x-www-form-urlencoded
对于浏览器原生的 form 表单, enctype 的值不指定的话, 默认就是这个家伙. 实际上大部分情况都使用它即可, 编码方式足够简单高效, 各方面支持也都很完备, 如各大浏览器调试工具, 各大抓包软件等.
- POST http://www.example.com HTTP/1.1
- Content-Type: application/x-www-form-urlencoded;charset=utf-8
- key1=val1&key2=val2
基本的请求类似上面这样, 数据的编码方式采用 key1=val1&key2=val2 的形式, 对其中的键值对都需要使用 URL Encode 编码一下. 其实就是和 GET 请求的数据提交格式是一样的, 只不过位置从 Request URL 上换到了 Request Body 里.
这种格式结构简单, 但对于数据层级较深的情况, 比如一些有复杂层级关系的接口数据, 这种方式就显得有点力不从心了. 另一方面, 对于需要上传二进制数据 (比如图像, 音频等文件), 这种方式就不那么高效了, 而且对于非 ASCII 码的数据就丢失了, 所以传文件的情况就不能使用这种方式.
适用场景: 数据量不大, 数据层级不深的情况下强烈建议这种数据提交格式.
multipart/form-data
当你需要提交文件, 非 ASCII 码的数据或者是二进制流数据, 则使用这种提交方式. 类似下面这个请求示例:
- POST http://www.example.com HTTP/1.1
- Content-Type:multipart/form-data; boundary=----webKitFormBoundaryPAlLG7hJKNYc4ft3
- ------WebKitFormBoundaryrGKCBY7qhFd3TrwA
- Content-Disposition: form-data; name="text"demo
- ------WebKitFormBoundaryPAlLG7hJKNYc4ft3
- Content-Disposition: form-data; name="file"; filename="demo.png"Content-Type: image/PNG
- ------WebKitFormBoundaryPAlLG7hJKNYc4ft3--
第二行指定编码方式 Content-Type 为 multipart/form-data, 紧接着生成一个分界线 boundary 即 ----WebKitFormBoundaryPAlLG7hJKNYc4ft3, 又臭又长的目的是为了避免和 Body 正文内容有冲突, 它的作用是用来分隔不同的字段.
Body 体分为多个结构类似的部分, 每一部分以 --boundary 开头, 因为本次请求生成的 boundary 为 ----WebKitFormBoundaryPAlLG7hJKNYc4ft3, 所以最终是 ------WebKitFormBoundaryPAlLG7hJKNYc4ft3. 接着是描述内容的元信息, 包括字段名称, 如果是文件则还有文件名称和文件类型. 接着留一空行, 然后才是字段值. 什么时候结束呢, 以 --boundary-- 标志结束.
这种方式本就是专为上传文件的场景设计的, 虽然你也可以使用这种方式传递普通数据, 但无疑会增加不少数据包的大小 (这么多 boundary 还是有不少空间占用的).
适用场景: 文件上传.
application/JSON
很明显在 JSON 格式火之前, 肯定没有它的, 前面说到使用什么提交数据方式是没有硬性规定的, 所以在 JSON 格式火了以后, 尤其以其优秀的数据结构表达能力, 逐渐流行开来, 现在我们对它完全不会陌生.
- POST http://www.example.com HTTP/1.1
- Content-Type: application/JSON;charset=utf-8{
- "name":"xfly","age": 24, "hobby":["x","xx","xxx"]
- }
适用场景: 数据结构较复杂, 层级较深的情况.
来源: http://www.css88.com/web/javascript/10684.html