Golang中http请求手动指定压缩后出现乱码问题处理
首先我们先来回顾下两个httpheader. Accept-Encoding和Content-Encoding是HTTP中用来对采用何种压缩格式传输body正文进行协定的一对header。工作原理如下:
浏览器发送请求,通过Accept-Encoding带上自己支持的内容编码格式列表 服务端从中挑选一个用来对正文进行编码,并通过Content-Encoding响应头指明响应编码格式。 浏览器拿到响应正文后,根据Content-Encoding进行解压缩。服务端若响应未压缩的正文,则不允许返回Content-Encoding。 压缩类型:
- gzip:表示采用 Lempel-Ziv coding (LZ77) 压缩算法,以及32位CRC校验的编码方式
- Compress:采用Lempel-Ziv-Welch (LZW) 压缩算法。
- deflate:表示采用 zlib 结构 (在 RFC 1950 中规定),和 deflate 压缩算法(在 RFC 1951 中规定)。
- identity:用于指代自身(未经过压缩和修改)。除非特别指明,这个标记始终可以被接受。
- Br:表示采用Brotli 算法的编码方式。
内容编码针对的只是传输正文。HTTP/1中,header始终是以ASCII文本传输,没有经过任何压缩;HTTP/2中才引入header压缩技术。
golang中在使用net/http发送http请求时,如果请求头中包含Accept-Encoding: gzip,且请求服务支持gzip压缩,那么在解析请求返回值时,需要手动解压
比如下面的代码:
req.Header.Add("Accept-Encoding", "compress,br,deflate")
res, err := client.Do(req)
if err != nil {
fmt.Println(err)
return
}
defer res.Body.Close()
//直接获取相应的body,无任何处理
mybody := res.Body
body, err := io.ReadAll()
if err != nil {
fmt.Println(err)
return
}
fmt.Println(string(body))
如果服务端也支持gzip发送压缩数据,那么客户端拿到响应后需要收到解压,像上面这样直接读取会出现乱码.
解决办法,要不就不要使用gzip进行压缩传输,这样服务端响应回来的数据也不会压缩,那么就可以直接读取了.或者就手动进行gzip的解压缩:
req.Header.Add("Accept-Encoding", "gzip,compress,br,deflate")
res, err := client.Do(req)
if err != nil {
fmt.Println(err)
return
}
defer res.Body.Close()
mybody := res.Body
//获取相应的body后进行解压缩处理
mybody, err = gzip.NewReader(res.Body)
body, err := io.ReadAll(mybody)
if err != nil {
fmt.Println(err)
return
}
fmt.Println(string(body))
本站文章除注明转载/出处外,均为本站原创或翻译,转载前请务必署名,转载请标明出处
最后编辑时间为:
2023/11/25 22:41
感谢大佬实用分享!!!!