Http的四种常见的POST提交数据方式
服务端通常根据请求头(headers) 中的 Content-Type 字段来获取请求中的消息主体是用何种方式编码,再对主体进行解析。这也正好解释了POST请求要先将请求头发送,再发送请求体。
Content-Type 指定了消息主体中的编码方式
因此,POST请求提交数据的方案,直接和Content-Type 和 消息主体两部分有关
http请求常见的Content-Type 分为四种:
- application/json
- x-www-form-urlencode
- multipart/form-data
- text/plain
1、application/x-www-form-urlencoded
http 中默认的提交数据的方式。浏览器的原生表单,如果不设置enctype属性,那么最终就会以application/x-www-form-urlencoded 方式提交数据,但在用于文本传输和MP3等大型文件的时候,这种编码的效率低下。
2、multipart/form-data
指定传输的数据为二进制类型,如图片、mp3、文件等。该格式会生成一个 boundary 字符串来分割请求头和请求体。
请求体内容各字段之间也有boundary 分割、但和分割请求头和请求体的boundary不同,且结束请求体也有一个boundary ,也是不一样的。
它会将表单的数据处理为一条消息,以标签为单元,用分隔符分开。既可以上传键值对,也可以上传文件。当上传的字段是文件时,会有Content-Type 来表明文件的类型。
content-disposition ,用来说明字段的一些信息
。
由于有boundary的隔离,所以multipart/form-data 既可以上传文件,也可以上传键值对。
它采用了键值对的方式,所以可以上传多个文件。
数据包说明
首先生成了一个boundary用于分割不同的字段,为了避免与正文内容重复,boundary很长很复杂。然后Content-Type里指明数据是以 multipart/form-data 编码的。本次请求的boundary是什么内容。消息主体按照字段的个数又分为多个结构体类似的部分,每部分都是以 -boundary开始
,紧接着是内容描述信息,然后是回车,最后是字段具体内容(文本或二进制)。如果传输的是文件,还要包括文件名和文件类型信息。消息主体最后以 -boundary-
标示结束。
这种方式一般用于上传文件,各大服务端语言对其有良好支持。
3、application/json
application/json 作为请求头,用来告诉服务端消息主体是序列化的JSON字符串。方便提交复杂的数据化结构,特别适合RESTful风格的接口
4、text/xml
使用http作为用户传输协议,xml作为编码方式的远程调用规范。
HTTP请求返回结果
返回时 ,json乱码的问题
可能出现的原因:
1、GBK 和UTF-8的编码方式不同,试着转换一下
2、accept-encoding 影响
请求的时候设置了header accept-encoding
为gzip 导致如何解析都是乱码。
原因是内容被gzip压缩,在网页请求的时候为了减小网页请求所消耗的带宽,提高数据传输的速度,通常会把数据进行压缩传输,设置accept-encoding为gzip ,deflate,br 代表数据压缩使用的编码方式。
还需要关注一个值 Content-encoding
(响应头中)
Content-encoding 指服务端的使用的是哪种压缩方式传输数据给你,accept-encoding 表示你发送请求时告诉服务器我可以使用哪些编码 解压缩服务器返回的数据。
服务端会根据你发送的 accent-encoding 来决定使用什么格式的content-encoding。
Sling 库
前言
Sling库是用于创建和发送API请求的GO http客户端库。
项目开发中发送http请求的场景,推荐使用sling库。Sling 本身是基于net/http 来处理发送请求,同时做了较好的封装,可以利用net/http 的一些特性(如 http trace),同时不必关心net/http 库的一些琐碎细节。
Sling 默认实现可以覆盖大部分对于http发送请求场景,同时可以通过实现Doer 和ResponseDecoder 接口来扩展个性化场景。
Sling 支持以下的主要功能:
- 支持GET/POST/PUT/PATCH/DELETE/HEAD
- 基于Base/Path 可以扩展和复用Sling
- query参数可以用结构体来Encode
- Request Body 支持 form 和json
- 可将Json 格式的 Response直接Decode到定义好的结构体
- 可扩展Response的Decoder,以及Doer。
2、Sling 使用方法
https://pkg.go.dev/github.com/dghubble/sling?utm_source=godoc
【GoCN酷Go推荐】灵活的Go http client库-Sling
参考URL: https://jishuin.proginn.com/p/763bfbd5b75f
Sling对http请求的要素method、baseUrl、Path、query、body、request、response等做了封装,基本使用可以参考https://github.com/dghubble/sling 上的示例代码。
可以通过实现ResponseDecoder和Doer的接口,来定制响应的decoder和发送请求的具体实现。
3、Sling 扩展
每个Sling 都会创建一个标准的 http.request 。
Request() 调用(例如,使用某些路径和查询参数)。您可能希望扩展现有的Sling以最大限度地从减少重复(例如常见客户端或基本URL)
每个Sling实例都提供了一种创建一个独立副本的New()方法,因此,子组的设置属性不会使父Sling 变异。(一个Sling可以new一个子sling,这个sling设置的属性不会影响父sling)
如下图,创建一个结构体在new 的函数生成一个sling实例,以后调用别的函数就可以直接使用
Sling 源码不支持multipart/form-data
Sling 本质还是使用的http 标准库