Golang中http请求手动指定压缩后出现乱码问题处理

/ 默认分类 / 1 条评论 / 2783浏览

Golang中http请求手动指定压缩后出现乱码问题处理

首先我们先来回顾下两个httpheader. Accept-Encoding和Content-Encoding是HTTP中用来对采用何种压缩格式传输body正文进行协定的一对header。工作原理如下:

浏览器发送请求,通过Accept-Encoding带上自己支持的内容编码格式列表 服务端从中挑选一个用来对正文进行编码,并通过Content-Encoding响应头指明响应编码格式。 浏览器拿到响应正文后,根据Content-Encoding进行解压缩。服务端若响应未压缩的正文,则不允许返回Content-Encoding。 压缩类型:

内容编码针对的只是传输正文。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))
  1. 感谢大佬实用分享!!!!